Last active
May 2, 2018 21:31
-
-
Save CMCDragonkai/b586ee9ecce297ceeeb3 to your computer and use it in GitHub Desktop.
Haskell: Unfold Anamorphism, the opposite of fold/reduce, it takes a seed and generators a large value
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- just to differentiate a finite data list vs an infinite codata list | |
-- list in Haskell is actually a codata, but it can be data | |
-- in this way we know when we talk about Stream we're meaning codata | |
type Stream a = [a] | |
-- take a generator, a seed, and return an infinite Stream (codata list) | |
-- I prefer using a name like "explode" or "blossom" or "spread" rather than "unfold" | |
unfold :: (b -> (a, b)) -> b -> Stream a | |
unfold f b = | |
let (a, b') = f b | |
in a : unfold f b' | |
-- a convenient function to produce a product from 2 functions | |
-- it's called a fork, because it results in a pair forming function | |
-- x -> (a, b) (thus forking x to a and b) | |
fork :: (x -> a, x -> b) -> x -> (a, b) | |
fork (f, g) a = (f a, g a) | |
-- mapping infinite lists | |
mapS :: (a -> b) -> Stream a -> Stream b | |
mapS f = | |
let generator = fork (f . head, tail) | |
in unfold generator | |
-- the generator must generate a product of a value and the next seed | |
generator a = (a, a + 1) | |
-- lazy evaluation allows us to store their expressions, not the value (which | |
-- would be infinitely large) | |
x = unfold generator 0 | |
-- we can do computations on the infinite list, like mapping the infinite list | |
y = mapS (+ 1) x | |
main = do | |
print "x" | |
print $ head x | |
print $ head . tail $ x | |
print $ head . tail . tail $ x | |
print "y" | |
print $ head y | |
print $ head . tail $ y | |
print $ head . tail . tail $ y |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment