I really don't understand what does scanl (\\sf -> fs ) g
do in this example. What is f
?
data Grid = Grid [Line]
data CellState = Dead | Alive deriving (Eq)
data Cell = Cell CellState Int deriving (Eq)
data Line = Line [Cell] Int deriving (Eq)
run :: Grid -> Int -> [Grid]
run g n = scanl (\s f -> f s) g $ replicate n playRound
playRound :: Grid -> Grid
From the documentation for scanl
:
scanl is similar to foldl, but returns a list of successive reduced values from the left:
scanl fz [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]
Note that
last (scanl fz xs) == foldl fz xs
.
So, scanl (\\sf -> fs ) g
behaves like this:
scanl (\s f -> f s) g [x1, x2, ...] == [g, x1 g, x2 (x1 g), ...]
Since \\sf -> fs
is an anonymous function which takes two arguments and applies the second to the first:
λ> (\s f -> f s) 2 (+1)
3
λ> (\s f -> f s) "Hello" length
5
Note that \\sf -> fs
could be written as flip ($)
.
So, specifically:
run g n = scanl (\s f -> f s) g $ replicate n playRound
Could be seen as:
run g n = [g, playRound g, playRound (playRound g), ...] -- Repeated n times.
If we look at the documentation of scanl :: (b -> a -> b) -> b -> [a]
we see that:
scanl is similar to foldl, but returns a list of successive reduced values from the left:
scanl fz [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]
Note that
last (scanl fz xs) == foldl fz xs.
So it starts with n initial value z
, and each time it applies a function to z
and the next element of the given list.
Here the initial value is g
, and the list is replicate n playRound
(which means a list of n
items, each item is playRound
). The function here takes the accumulator s
, and an element of the list (here always playRound
), and the outcome of fs
(in this case playRound s
), is the next item in the list.
So it will produce a list:
[g, playRound g, playRound (playRound g), ...]
and the list will contain n+1
items.
Probably a more elegant approach should have been:
run :: Grid -> Int -> [Grid]
run g n = take (n+1) $ iterate playRound g
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.