Skip to content

Instantly share code, notes, and snippets.

@slabko
Created July 9, 2016 22:06
Show Gist options
  • Save slabko/40ec6b839c6d7d69207cd80e97fd11ae to your computer and use it in GitHub Desktop.
Save slabko/40ec6b839c6d7d69207cd80e97fd11ae to your computer and use it in GitHub Desktop.
Scott Encoding
{-# LANGUAGE RankNTypes #-}
module ScottEncoding where
import Data.Monoid
data ListS a = ListS { uncons :: forall r. (a -> ListS a -> r) -> r -> r }
consS :: a -> ListS a -> ListS a
consS x xs = ListS (\f z -> f x xs)
uncons' :: (a -> ListS a -> r) -> r -> ListS a -> r
uncons' f z xs = uncons xs f z
nilS :: ListS a
nilS = ListS $ const id
toList :: Foldable t => t a -> ListS a
toList = foldMap (`consS` nilS)
instance Functor ListS where
fmap f = uncons' (\x xs -> consS (f x) (fmap f xs)) nilS
instance Foldable ListS where
foldr f z = uncons' (\x xs -> f x (foldr f z xs)) z
instance Applicative ListS where
pure x = consS x nilS
fs <*> xs = foldr mappend nilS $ fmap (\f -> fmap f xs) fs
instance Monoid (ListS a) where
mempty = nilS
mappend xs ys = foldr consS ys xs
instance Traversable ListS where
sequenceA = uncons' (\x xs -> consS <$> x <*> sequenceA xs) (pure nilS)
fromList :: ListS a -> [a]
fromList = foldMap (:[])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment