Nothing 3 | Just a 4 5 data Either a b 6 = Left a 7 | Right b 8 9 data List a 10 = Empty 11 | Cons a (List a) 12 13 data Tree a 14 = Leaf a 15 | Branch (Tree a) (Tree a) 16 8
Empty 3 | Cons a (List a) 4 5 cdr :: List a -> List a 6 cdr Empty = ?? 7 cdr (Cons _ rest) = rest 8 9 car :: List a -> a 10 car Empty = ?? 11 car (Cons a _) = a 12 10
Empty 3 | Cons a (List a) 4 5 cdr :: List a -> List a 6 cdr Empty = Empty 7 cdr (Cons _ rest) = rest 8 9 car :: List a -> Maybe a 10 car Empty = Nothing 11 car (Cons a _) = Just a 12 13 data Maybe a = Nothing | Just a 14 11
= runHandlerM $ do Just token <- reqHeader “Authorisation” auth <- liftIO $ post (showRoute ValidateR) token if isValid auth then status 403 >> json err else json albums 14
3 | Cons a (List a) 4 5 concat :: List a -> List a -> List a 6 concat Empty b = b 7 concat a Empty = a 8 concat (Cons x xs) b@(Cons _ _) 9 = Cons x (concat xs b) 10 15
data, next = None ): 3 self.data = data 4 self.next = next 5 6 def concat(A, B): 7 current = A 8 while current.next != None: 9 current = current.next 10 current.next = B 11 return A 16
current.next != None: current = current.next current.next = B return A 17 concat Empty b = b concat a Empty = a concat (Cons x xs) b = Cons x (concat xs b) HASKELL FIGHT!
current.next != None: current = current.next current.next = B return A 18 concat Empty b = b concat a Empty = a concat (Cons x xs) b = Cons x (concat xs b) HASKELL TEST assertEq(concat('','bar'), 'bar') assertEq(concat('foo',''), 'foo') assertEq(concat(‘foo’,'bar'), 'foobar')
current.next != None: current = current.next current.next = B return A 19 concat Empty b = b concat a Empty = a concat (Cons x xs) b = Cons x (concat xs b) HASKELL
WAY IS TO MAKE IT SO COMPLICATED THAT THERE ARE NO OBVIOUS DEFICIENCIES, AND THE OTHER WAY IS TO MAKE IT SO SIMPLE THAT THERE ARE OBVIOUSLY NO DEFICIENCIES. - C.A.R. Hoare, 1980 ACM Turing Award Lecture HASKELL 101 20
-> b -> d) -> (x -> b) -> a -> x -> d 2 compose2 f m a x = f a (m x) 3 foldMap f m a (x:xs) = foldMap f m (f a (m x)) xs 4 = foldMap f m (compose2 f m a x) xs foldMap f m a (x:xs) = fold (compose2 f m) a x xs 37
(foldMap) which was actually not needed ▸ Our existing machinery (fold) turned out to be powerful enough to support our logic ▸ We reduced code complexity by introducing another “orthogonal” and “generic” shared vocabulary (compose2) 40
f (Leaf a) = Leaf (f a) 4 fmap f (Branch x y) = Branch (fmap f x) (fmap f y) 5 6 instance Foldable Tree where 7 foldl f b (Leaf a) = f b a 8 foldl f b (Branch x y) = ?? (foldl f b x) (foldl f b y) 50
-> b) -> (b -> b -> b) -> b 2 -> Tree a -> b 3 foldTree f g b (Leaf a) = f b a 4 foldTree f g b (Branch x y) 5 = g (foldTree f g b x) (foldTree f g b y) 51
a -> b) -> (b -> b -> b) -> b 2 -> Tree a -> b 3 foldTree f g b (Leaf a) = f b a 4 foldTree f g b (Branch x y) 5 = g (foldTree f g b x) (foldTree f g b y) 52