Multiplication tables: Difference between revisions
Content added Content deleted
Line 324: | Line 324: | ||
12 144 |
12 144 |
||
"</pre> |
"</pre> |
||
As an alternative to iteration, we could write the top level more declaratively, drawing on a library of generic functions. |
|||
{{trans|JavaScript}} |
|||
<lang AppleScript>on run |
|||
showTable(table(1, 12)) |
|||
end run |
|||
-- Int -> Int -> [[String]] |
|||
on table(m, n) |
|||
script mf |
|||
property rng : range(m, n) |
|||
on lambdaX(x) |
|||
set mf to my closure's mf |
|||
{x & concatMap(mf's rng, mClosure(mf's lambdaY, {x:x}))} |
|||
end lambdaX |
|||
on lambdaY(y) |
|||
set x to my closure's x |
|||
if y < x then |
|||
{""} |
|||
else |
|||
{(x * y) as text} |
|||
end if |
|||
end lambdaY |
|||
end script |
|||
set rng to mf's rng |
|||
set lstTable to {{"x"} & rng} & concatMap(rng, mClosure(mf's lambdaX, {mf:mf})) |
|||
end table |
|||
-- [[String]] -> String |
|||
on showTable(lstTable) |
|||
script mf |
|||
on showLine(lstLine) |
|||
set mf to mf of my closure |
|||
intercalate(" ", map(lstLine, mClosure(mf's showCell, {mf:mf}))) |
|||
end showLine |
|||
on showCell(cell) |
|||
(characters -4 thru -1 of (" " & cell)) as string |
|||
end showCell |
|||
end script |
|||
intercalate(linefeed, map(table(1, 12), mClosure(mf's showLine, {mf:mf}))) |
|||
end showTable |
|||
-- GENERIC LIBRARY FUNCTIONS |
|||
-- [a] -> (a -> b) -> [b] |
|||
on concatMap(xs, f) |
|||
reduce(map(xs, f), my concat, {}) |
|||
end concatMap |
|||
-- a -> a -> [a] |
|||
on concat(a, b) |
|||
a & b |
|||
end concat |
|||
-- [a] -> (a -> b) -> [b] |
|||
on map(xs, f) |
|||
set mf to mReturn(f) |
|||
set lng to length of xs |
|||
set lst to {} |
|||
repeat with i from 1 to lng |
|||
set end of lst to mf's lambda(item i of xs, i, xs) |
|||
end repeat |
|||
return lst |
|||
end map |
|||
-- [a] -> (a -> b) -> b -> [b] |
|||
on reduce(xs, f, startValue) |
|||
set mf to mReturn(f) |
|||
set v to startValue |
|||
set lng to length of xs |
|||
repeat with i from 1 to lng |
|||
set v to mf's lambda(v, item i of xs, i, xs) |
|||
end repeat |
|||
return v |
|||
end reduce |
|||
-- Text -> [Text] -> Text |
|||
on intercalate(strText, lstText) |
|||
set {dlm, my text item delimiters} to {my text item delimiters, strText} |
|||
set strJoined to lstText as text |
|||
set my text item delimiters to dlm |
|||
return strJoined |
|||
end intercalate |
|||
-- m..n |
|||
on range(m, n) |
|||
set lng to (n - m) + 1 |
|||
set base to m - 1 |
|||
set lst to {} |
|||
repeat with i from 1 to lng |
|||
set end of lst to i + base |
|||
end repeat |
|||
return lst |
|||
end range |
|||
-- Lift handler into 1st class object |
|||
-- Handler -> Script |
|||
on mReturn(f) |
|||
if class of f is script then return f |
|||
script |
|||
property lambda : f |
|||
end script |
|||
end mReturn |
|||
-- Lift handler, with bindings, into 1st class object |
|||
-- Handler -> Record -> Script |
|||
on mClosure(f, recBindings) |
|||
script |
|||
property closure : recBindings |
|||
property lambda : f |
|||
end script |
|||
end mClosure</lang> |
|||
{{Out}} |
|||
<pre> x 1 2 3 4 5 6 7 8 9 10 11 12 |
|||
1 1 2 3 4 5 6 7 8 9 10 11 12 |
|||
2 4 6 8 10 12 14 16 18 20 22 24 |
|||
3 9 12 15 18 21 24 27 30 33 36 |
|||
4 16 20 24 28 32 36 40 44 48 |
|||
5 25 30 35 40 45 50 55 60 |
|||
6 36 42 48 54 60 66 72 |
|||
7 49 56 63 70 77 84 |
|||
8 64 72 80 88 96 |
|||
9 81 90 99 108 |
|||
10 100 110 120 |
|||
11 121 132 |
|||
12 144</pre> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |