class Functor

class Functor f where               -- RR s.8.1 p.109
  fmap :: (a -> b) -> f a -> f b

instance Functor [] where           -- RR s.8.1 p.113
  fmap = map   -- i.e. the traditional Lisp map ...
  -- map g []     = []
  -- map g (x:xs) = (g x):(map g xs)

For example, declare a binary-tree type and make it an instance of class Functor:


module Main where

data Tree e = Fork e (Tree e) (Tree e) | EmptyTree deriving (Show)

instance Functor Tree where
  fmap f EmptyTree    = EmptyTree
  fmap f (Fork e l r) = Fork (f e) (fmap f l) (fmap f r)      --say

-- ----------------------------------------------------------------
l1 = ["anna", "bill", "carol"]                           --[String]
t1 = Fork "bill" (Fork "anna"  EmptyTree EmptyTree)   --Tree String
                 (Fork "carol" EmptyTree EmptyTree)
a2A 'a' = 'A'                                        --Char -> Char
a2A ch  = ch  --otherwise
g = map a2A                                      --String -> String

main =
    putStrLn(show(fmap g l1))                 --[String];      f=[]
 >> putStrLn(show(fmap g t1))                 --Tree String; f=Tree
 >> fmap g (readFile "abc.txt") >>= putStrLn  --IO String;     f=IO
-- ---------------------------------------------------LA--11/2005--
file abc.txt:
anna bill carol

Note that the one operator/program 'g' is applied to a [String] (list of String), a Tree (of) String, and an IO String (RR s.8.1 pp.111).  fmap defines what happens to a Functor instance -- to a "structure". g defines what happens to an element.

RR = revised report, CUP, 2003.