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}}==