data List a = Cons a (List a) | Nil -- deriving Show -- We could have it "deriving( Show )", but I want my -- own printable/string representation, so: instance Show a => Show (List a) where show (Cons a b) = "<" ++ show a ++ " " ++ show b ++ ">" show Nil = "<>" -- Right-associative list builder to emulate what ":" does: infixr 5 `cons` cons x y = Cons x y -- length function len Nil = 0 len (Cons x y) = 1 + len y -- head, tail, length, null hd :: List a -> a hd (Cons x _) = x -- What to do for hd Nil? See why-no-head-of-empty-list.txt for why this is the best choice. hd Nil = error "no head in an empty List" -- In this definition of "tail", the second pattern is redundant, but tl -- of Nil (empty list) is not defined. Fix this! tl (Cons _ xs) = xs tl (Cons _ Nil) = Nil -- What to do for tl Nil? -- What does this do? nl Nil = True nl (Cons _ _) = False -- Finally, we could write our lists with # instead of `cons`, -- which is less syntactically cumbersome, like this: "1 # 2 # 3 # Nil" -- Note the () syntax for the native infix form, and ` ` for the native -- prefix form above. infixr 5 # (#) a b = Cons a b