Monads/List monad: Difference between revisions
Content added Content deleted
(→{{header|AppleScript}}: Some simplification - normalised argument sequence in a couple of higher-order functions) |
|||
Line 15: | Line 15: | ||
We can use a list monad in AppleScript to express set comprehension for the Pythagorean triples, but the lack of nestable first class (and anonymous) functions means that the closure can only be achieved using script objects, which makes the idiom rather less direct and transparent. AppleScript is creaking at the seams here. |
We can use a list monad in AppleScript to express set comprehension for the Pythagorean triples, but the lack of nestable first class (and anonymous) functions means that the closure can only be achieved using script objects, which makes the idiom rather less direct and transparent. AppleScript is creaking at the seams here. |
||
<lang AppleScript> |
<lang AppleScript>on run |
||
on run |
|||
-- Pythagorean triples drawn from integers in the range [1..n] |
-- Pythagorean triples drawn from integers in the range [1..n] |
||
-- {(x, y, z) | x <- [1..n], y <- [x+1..n], z <- [y+1..n], (x^2 + y^2 = z^2)} |
-- {(x, y, z) | x <- [1..n], y <- [x+1..n], z <- [y+1..n], (x^2 + y^2 = z^2)} |
||
Line 27: | Line 25: | ||
end run |
end run |
||
-- pythagoreanTriples :: Int -> [(Int, Int, Int)] |
|||
on pythagoreanTriples(maxInteger) |
on pythagoreanTriples(maxInteger) |
||
script |
script lambdaX |
||
on lambda(x) |
|||
script lambdaY |
|||
on |
on lambda(y) |
||
script lambdaZ |
|||
on lambda(z) |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
else |
|||
[] |
|||
end if |
|||
end |
end lambda |
||
end script |
|||
bind(lambdaZ, range(1 + y, maxInteger)) |
|||
end lambda |
|||
end script |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
bind(lambdaY, range(1 + x, maxInteger)) |
|||
⚫ | |||
⚫ | |||
end script |
end script |
||
bind(lambdaX, range(1, maxInteger)) |
|||
end pythagoreanTriples |
end pythagoreanTriples |
||
-- |
-- MONADIC FUNCTIONS (for list monad) |
||
-- Monadic bind for lists is simply ConcatMap |
-- Monadic bind for lists is simply ConcatMap |
||
-- which applies a function f directly to each value in the list, |
-- which applies a function f directly to each value in the list, |
||
-- and returns the set of results as a concat-flattened list |
-- and returns the set of results as a concat-flattened list |
||
⚫ | |||
-- bind :: (a -> [b]) -> [a] -> [b] |
|||
⚫ | |||
reduce(map(xs, f), my concat, {}) |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
foldl(concat, {}, map(f, xs)) |
|||
end bind |
end bind |
||
-- Monadic return/unit/inject for lists just wraps a value in a list |
-- Monadic return/unit/inject for lists: just wraps a value in a list |
||
-- a -> [a] |
-- a -> [a] |
||
on unit(a) |
on unit(a) |
||
Line 76: | Line 78: | ||
end unit |
end unit |
||
⚫ | |||
-- GENERIC LIBRARY FUNCTIONS |
|||
⚫ | |||
⚫ | |||
⚫ | |||
set mf to mReturn(f) |
set mf to mReturn(f) |
||
set lng to length of xs |
set lng to length of xs |
||
Line 87: | Line 92: | ||
end map |
end map |
||
-- list, function, initial accumulator value |
|||
-- |
-- foldl :: (a -> b -> a) -> a -> [b] -> a |
||
on foldl(f, startValue, xs) |
|||
-- v: current accumulator value |
|||
-- x: current item in list |
|||
-- i: [ 1-based index in list ] optional |
|||
-- l: [ a reference to the list itself ] optional |
|||
-- [a] -> (a -> b) -> b -> [b] |
|||
on reduce(xs, f, startValue) |
|||
set mf to mReturn(f) |
set mf to mReturn(f) |
||
Line 103: | Line 103: | ||
end repeat |
end repeat |
||
return v |
return v |
||
end |
end foldl |
||
-- |
-- range :: Int -> Int -> [Int] |
||
on |
on range(m, n) |
||
if n < m then |
|||
⚫ | |||
end concat |
|||
else |
|||
⚫ | |||
⚫ | |||
-- Function - > inherited name space -> Script object |
|||
⚫ | |||
-- Handler -> Record -> Script |
|||
⚫ | |||
on mClosure(f, recBindings) |
|||
set end of lst to i |
|||
⚫ | |||
end repeat |
|||
property closure : recBindings |
|||
⚫ | |||
⚫ | |||
end range |
|||
end mClosure |
|||
-- Script | Handler -> Script |
-- Script | Handler -> Script |
||
Line 130: | Line 129: | ||
end if |
end if |
||
end mReturn |
end mReturn |
||
-- m..n |
|||
⚫ | |||
set lng to (n - m) + 1 |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
return lst |
|||
end range |
|||
</lang> |
</lang> |
||
Line 146: | Line 134: | ||
{{Out}} |
{{Out}} |
||
< |
<lang AppleScript>{{3, 4, 5}, {5, 12, 13}, {6, 8, 10}, {7, 24, 25}, {8, 15, 17}, {9, 12, 15}, {12, 16, 20}, {15, 20, 25}}</lang> |
||
=={{header|Clojure}}== |
=={{header|Clojure}}== |