{-# LANGUAGE GADTs #-} -- Types: read, understand and extend Haskell programs which use advanced type system features -- Types.Class: type classes, newtypes, deriving, ... -- Types.GADT: (generalised) algebraic datatypes & type families -- Types.HOT: functors, monads and monad transformers import Control.Monad (liftM2) data Expr t where C :: Char -> Expr Char I :: Int -> Expr Int (:@) :: Expr (a -> b) -> Expr a -> Expr b Nil :: Expr [a] Cons :: Expr (a -> [a] -> [a]) Replicate :: Expr (Int -> a -> [a]) Length :: Expr ([a] -> Int) -- Added later V :: Name -> Expr String type Name = Int eval :: Expr t -> t eval (C c) = c eval (I i) = i eval (f :@ x) = (eval f) (eval x) eval Nil = [] eval Cons = (:) eval Replicate = replicate eval Length = length test = eval (Replicate :@ (I 5) :@ Nil) stringLit :: String -> Expr String stringLit = foldr (\x e -> Cons :@ C x :@ e) Nil -- Added later: eval2 :: (Name -> Maybe String) -> Expr t -> Maybe t eval2 lookup (V v) = lookup v eval2 l (C c) = Just c eval2 l (I i) = Just i eval2 l (f :@ x) = liftM2 ($) (eval2 l f) (eval2 l x) eval2 l Nil = Just [] eval2 l Cons = Just (:) eval2 l Replicate = Just replicate eval2 l Length = Just length -- Changes: -- * new constructor for Int-labelled variables -- * Monadic (to handle variable lookup failure) -- * eval2 has a new case for the variables test2 = eval2 (const (Just "hej")) (Replicate :@ (Length :@ (V 1)) :@ V 1) ----------------------------------------------------------------