Skip to content

Instantly share code, notes, and snippets.

@cartazio
Created May 15, 2016 03:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cartazio/60eac732e7ac162916eaf828c9b1483c to your computer and use it in GitHub Desktop.
Save cartazio/60eac732e7ac162916eaf828c9b1483c to your computer and use it in GitHub Desktop.
copattern hs
{-# LANGUAGE GADTs, RankNTypes #-}
main = putStrLn "hello!"
-- StreamModel is what we ordinarily write as "Stream" in haskell,
-- though is not ideal for a variety of reasons.
data StreamModel a = StreamModel { head :: a , tail :: StreamModel a}
data StreamTag a {- param list -} res {- result type! -} where
HeadTag :: StreamTag a a
TailTag :: StreamTag a (Stream a)
newtype Stream a = Stream { unStream :: (forall res . StreamTag a res -> res) }
headStream:: Stream a -> a
headStream (Stream f) = f HeadTag
tailStream :: Stream a -> Stream a
tailStream (Stream f) = f TailTag
-- this is just zipWith for Stream,
rawRawZipWith :: (a -> b ->c ) -> Stream a -> Stream b -> Stream c
rawRawZipWith f sta stb = Stream $ \ x ->
case x of
HeadTag -> f (headStream sta) (headStream stb)
TailTag -> rawRawZipWith f (tailStream sta) (tailStream stb)
--- edit1: heres how to go from Stream (the coinductive definition)
--- to StreamModel (the usual stream definition in haskell)
stream2StreamModel :: Stream a -> StreamModel a
stream2StreamModel strm = StreamModel (headStream strm) (tailStream strm)
-- edit2 : clarified that the StreamModel type is only included for simplicity :)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment