Skip to content

Instantly share code, notes, and snippets.

@zelinskiy
Created February 3, 2017 14:15
Show Gist options
  • Save zelinskiy/0a1ad89d9ac0c4ddbc8fde05bdcbb3e3 to your computer and use it in GitHub Desktop.
Save zelinskiy/0a1ad89d9ac0c4ddbc8fde05bdcbb3e3 to your computer and use it in GitHub Desktop.
Stream is a Comonad
module Main where
class Functor w => Comonad w where
extract :: w a -> a
duplicate :: w a -> w (w a)
extend :: (w a -> b) -> w a -> w b
data Stream a = Cons a (Stream a)
instance Functor Stream where
fmap f (Cons x xs) = Cons (f x) (fmap f xs)
instance Comonad Stream where
extract (Cons x _) = x
duplicate xs@(Cons _ xs') = Cons xs (duplicate xs')
extend f xs@(Cons _ xs') = Cons (f xs) (extend f xs')
replicateS :: (a -> a) -> a -> Stream a
replicateS f t = Cons t (replicateS f (f t))
sumS :: Num a => Int -> Stream a -> a
sumS n (Cons a as) = if n <= 0 then 0 else a + sumS (n - 1) as
showS :: Stream Int -> Stream String
showS s = extend (\(Cons x _) -> show x) s
advanceS :: Stream a -> Stream a
advanceS (Cons a as) = as
extractS' :: [a] -> Int -> Stream a -> [a]
extractS' acc 0 s = acc
extractS' acc n s = extractS' (extract s:acc) (n-1) (advanceS s)
extractS n s = extractS' [] n s
main = print $ extractS 20 (showS (replicateS (*2) 1))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment