Skip to content

Instantly share code, notes, and snippets.

@rrnewton
Created August 5, 2015 01:11
Show Gist options
  • Save rrnewton/e93c800318743fed1b11 to your computer and use it in GitHub Desktop.
Save rrnewton/e93c800318743fed1b11 to your computer and use it in GitHub Desktop.
SpecList
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Data.Proxy
class SpecList a where
type List a :: *
slNil :: Proxy a -> List a
slCons :: a -> List a -> List a
slLength :: List a -> Int
slFoldr :: (a -> b -> b) -> b -> List a -> b
slMap :: SpecList b
=> (a -> b) -> List a -> List b
data IntList
= ILNil
| ILCons {-# UNPACK #-} !Int IntList
intListLength :: IntList -> Int
intListLength ILNil = 0
intListLength (ILCons _ l) = 1 + intListLength l
intListFoldr :: (Int -> b -> b) -> b -> IntList -> b
intListFoldr _ acc ILNil = acc
intListFoldr f acc (ILCons i rest) = f i (intListFoldr f acc rest)
intListMap :: forall b . SpecList b
=> (Int -> b) -> IntList -> List b
intListMap _ ILNil = slNil (Proxy::Proxy b)
intListMap f (ILCons i rest) = slCons (f i) (intListMap f rest)
instance SpecList Int where
type List Int = IntList
slNil (_ :: Proxy Int) = ILNil :: List Int
slCons = ILCons
slLength = intListLength
slFoldr = intListFoldr
slMap = intListMap
main :: IO ()
main = return ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment