member [] y = False member (x:xs) y = (x == y) || (member xs y) sumOfSquares [] = 0 sumOfSquares (x:xs) = x*x + sumOfSquares xs square :: Num a => a -> a square x = x * x squares :: (Num t, Num t1, Num t2) => (t, t1, t2) -> (t, t1, t2) squares (x,y,z) = (square x, square y, square z) -- Haskell member function mmember :: Eq a => [a] -> a -> Bool mmember [] y = False mmember (x:xs) y = x == y || (mmember xs y) -- Haskell member function, passing equality explicity member' :: (a->a->Bool) -> [a] -> a -> Bool member' eq [] y = False member' eq (x:xs) y = (eq x y) || (member' eq xs y) -- Sorting function with explicit comparison qsort:: (a -> a -> Bool) -> [a] -> [a] qsort comp [] = [] qsort comp (x:xs) = qsort comp (filter (comp x) xs) ++ [x] ++ qsort comp (filter (not.comp x) xs) myCmp x y = x > y sortedList = qsort myCmp [2,4,2,7,2,3] -- Haskell numeric function using overloading parabola :: Num a => a -> a parabola x = (x * x) + x -- Haskell numeric function, passing + and * explicity parabola' :: ((a->a->a), (a->a->a)) -> a -> a -- parabola' (plus,times) x = (x `times` x) `plus` x parabola' (plus, times) x = plus (times x x) x -- Haskell numeric function, Dictionary translation -- Type of dictionary: What a type class declaration specifies. data PlusTimesDict a = MkPlusTimesDict (a->a->a) (a->a->a) -- Accessor functions get_plus :: PlusTimesDict a -> (a->a->a) get_plus (MkPlusTimesDict p t) = p get_times :: PlusTimesDict a -> (a->a->a) get_times (MkPlusTimesDict p t) = t intPlus :: Int -> Int -> Int intPlus = (+) intTimes :: Int -> Int -> Int intTimes = (*) floatPlus :: Float -> Float -> Float floatPlus = (+) floatTimes :: Float -> Float -> Float floatTimes = (*) -- Dictionary construction: what a type class instance specifies. intDict = MkPlusTimesDict intPlus intTimes floatDict = MkPlusTimesDict floatPlus floatTimes -- Function with explicit dictionary parabola''' :: PlusTimesDict a -> a -> a parabola''' dict x = let plus = get_plus dict times = get_times dict in plus (times x x) x -- Or more concisely... parabola'' :: PlusTimesDict a -> a -> a parabola'' dict x = get_plus dict (get_times dict x x) x y = parabola'' intDict 10 z = parabola'' floatDict 3.14 -- only types a that have a corresponding dictionary of type -- PlusTimesDict can be passed to the parabola'' function. -- Type classes provide a way of managing this plumbing automatically. -- Type class causes compiler to generate dictionary type. -- Each instance declaration causes compiler to generate a value of the dictionary, -- corresponding to the operations for the type being instantiated. -- Each function that has a qualified type will be rewritten by the compiler -- to take an extra dictionary parameter and to use the dictionary to look up the -- appropriate code for each "overloaded" function. -- parabola :: PlusTimesDict a => a -> a -- parabola x = x * x + x -- will lead to parabola'' definition. data Cpx a = Cpx a a deriving (Eq, Show) instance Num a => Num (Cpx a) where (Cpx r1 i1) + (Cpx r2 i2) = Cpx (r1+r2) (i1+i2) (Cpx r1 i1) * (Cpx r2 i2) = Cpx (r1*r2) (i1*i2) (Cpx r1 i1) - (Cpx r2 i2) = Cpx (r1-r2) (i1-i2) negate (Cpx r i) = Cpx (negate r) (negate i) abs (Cpx r i) = Cpx (abs r) (abs i) signum (Cpx r i) = Cpx (signum r) (signum i) fromInteger n = Cpx (fromInteger n) 0 c1 = 1 :: Cpx Int c2 = 2 :: Cpx Int c3 = Cpx 1 3 c4 = c1 + c3 c5 = c1 * c2 c6 = parabola c4 i1 = parabola 3 data Color = Red | Green | Blue deriving (Read, Show, Eq, Ord) s1 = show Red c = (read "Red" :: Color ) p1 = (2,3) p2 = (5,1) newtype UniqueID = UniqueID (Int,Int) deriving (Eq, Ord, Show) class Foo a where (@@@@) :: a -> a -> Bool instance Foo Int where i @@@@ j = i == j instance Foo Char where i @@@@ j = i == j instance (Foo a, Foo b) => Foo (a,b) where (u,v) @@@@ (x,y) = (u @@@@ x) && (v @@@@ y) -- instance Foo a => Foo [a] where -- [] @@@@ [] = True -- (x:xs) @@@@ (y:ys) = x @@@@ y && xs @@@@ ys instance Foo String where s @@@@ s2 = s == s2 -- Myexample :: (Ord a) => a -> [a] -> Bool myexample z xs = case xs of [] -> False (y:ys) -> y > z || (y==z && ys ==[z]) memsq :: (Eq a, Num a) => [a] -> a -> Bool memsq xs x = member xs (square x) listMap :: (a -> b) -> [a] -> [b] listMap f [] = [] listMap f (x:xs) = f x : listMap f xs data Tree a = Leaf a | Node(Tree a, Tree a) deriving Show mapTree :: (a -> b) -> (Tree a -> Tree b) mapTree f (Leaf x) = Leaf (f x) mapTree f (Node(l,r)) = Node (mapTree f l, mapTree f r) t1 = Node(Node(Leaf 3, Leaf 4), Leaf 5) data Opt a = Some a | None deriving Show mapOpt :: (a -> b) -> (Opt a -> Opt b) mapOpt f None = None mapOpt f (Some x) = Some (f x) o1 = Some 10 class HasMap f where map' :: (a->b) ->(f a -> f b) instance HasMap [] where map' f [] = [] map' f (x:xs) = f x : map' f xs instance HasMap Tree where map' f (Leaf x) = Leaf (f x) map' f (Node(t1,t2)) = Node(map' f t1, map' f t2) instance HasMap Opt where map' f (Some s) = Some (f s) map' f None = None r1 = map' (\x->x+1) [1,2,3] r2 = map' (\x->x+1) (Node(Leaf 1, Leaf 2)) r3 = map' (\x->x+1) (Some 1)