Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr...
Transcript of Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr...
![Page 1: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/1.jpg)
Algebraic TypesChapter 14 of Thompson
![Page 2: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/2.jpg)
Types so far …
Base types Int, Integer, Float, Bool, CharComposite types:
tuples (t1,t2,…,tn)lists [t1]functions (t1 -> t2)
Algebraic types enumerated, product (record), sum (union)Now, we will see more types that are recursive and polymorphic
![Page 3: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/3.jpg)
Recursive types: example
data NTree = NilT |Node Integer NTree NTree
Such types allow us to build data structures of arbitrary size.
12
10 17
14 20• •
• • • •
![Page 4: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/4.jpg)
![Page 5: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/5.jpg)
Polymorphic types: example
data Maybe a = Nothing | Just a
Built into the Haskell prelude and used for modelling program errors.
Reusable in different situations, such as the built in list type.
![Page 6: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/6.jpg)
Review: algebraic data types in general
data Typename= Con1 t11 t12 … t1i |
Con2 t21 t22 … t2j |…Conm tm1 tm2 … tmk
Each Coni is a constructor, followed by n types, where n ≥ 0, allowing us to build values of the type by using the constructor as a function:Coni :: ti1 -> ti2 -> … -> tin -> Typename
![Page 7: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/7.jpg)
Examples
Enumerated types have constructors with no arguments:data Season = Spring | Summer | Autumn | Winter
Product types have a single constructor:data People = Person Name Age
Sum types have a number of constructors taking different arguments:data Shape = Circle Float |
Rectangle Float Float
![Page 8: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/8.jpg)
Examples: pattern matching
To distinguish among alternatives and to extract components:
area :: Shape -> Floatarea (Circle r) = pi*r*rarea (Rectangle h w) = h*w
![Page 9: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/9.jpg)
Recursive algebraic types: example
A recursive type is a type described in terms of itself:data Expr = Lit Integer |
Add Expr Expr |Sub Expr Expr
This describes an integer expression as something that one of:a literal, like 42;the sum of two subexpressions; orthe difference between two subexpressions
expr1 = Lit 2expr2 = Add (Lit 2) (Lit 3)expr3 = Add (Sub (Lit 3) (Lit 1)) (Lit 3)
Expr
Lit 2
Expr
Add
Lit 2 Lit 3
Expr
Add
Sub Lit 3
Lit 3 Lit 1
![Page 10: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/10.jpg)
Primitive recursion over expressions
[Live coding for eval and show over integer expressions]
![Page 11: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/11.jpg)
Recursive algebraic types: trees
A tree is either nil (empty) or the joining of two subtrees into a tree node:data NTree = NilT |
Node Integer NTree NTreeFor example:
treeEx1 = Node 10 NilT NilTtreeEx2 = Node 17 (Node 14 NilT NilT)
(Node 20 NilT NilT)
Similarly, a list is either the empty list []or constructed from a head and a tail using :
list1 = [10, [], []]list2 = [17, [14, [], []], [20, [], []]]
10
• •
17
14 20
• • • •
![Page 12: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/12.jpg)
Primitive recursion over trees
[live coding for sumTree, depth, occurs]
![Page 13: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/13.jpg)
More recursion over expressions
Since addition is associative, it would be nice to present integer expressions including addition in a normalized right-associative form:
(2+3)+4 = 2+(3+4)((2+3)+4)+5 = 2+(3+(4+5))((2-((6+7)+8))+4)+5 = (2-(6+(7+8)))+(4+5)
Aim: spot occurrences ofAdd (Add e1 e2) e3
and transform them toAdd e1 (Add e2 e3)
[live coding for assoc]
![Page 14: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/14.jpg)
Non-primitive recursion over expressions
assoc :: Expr -> Expr
assoc (Add (Add e1 e2) e3)= assoc (Add e1 (Add e2 e3))
assoc (Add e1 e2) = Add (assoc e1) (assoc e2)
assoc (Sub e1 e2) = Sub (assoc e1) (assoc e2)
assoc (Lit n) = Lit n
![Page 15: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/15.jpg)
Termination
assoc (Add (Add e1 e2) e3)= assoc (Add e1 (Add e2 e3))
The RHS makes progress by moving the expression tree from left-associative to right-associative.None of the other equations move a plus in the other direction, so after applying the above equation some finite number of times there will be no more exposed addition symbols at the top level of the LHS.
![Page 16: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/16.jpg)
Syntax: infix constructors
Can also write:data Expr' = Lit' Integer |
Expr' :+: Expr' |Expr' :-: Expr'
The infix operators must start with :
![Page 17: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/17.jpg)
Mutual recursion
data Person = Adult Name Address Bio |Child Name
data Bio = Parent String [Person] |NonParent String
type Name = Stringtype Address = [String]
![Page 18: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/18.jpg)
Mutual recursion
showPerson (Adult nm ad bio) = show nm ++ show ad ++ showBio bio
showPerson (Child nm) = show nm
showBio (Parent st perList)= st ++ concat (map showPerson perList)
showBio (NonParent st)= st
![Page 19: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/19.jpg)
![Page 20: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/20.jpg)
Polymorphic algebraic types
Type variables can be used to make an algebraic type polymorphic.Example:
data Pairs a = Pr a a
pair1 = Pr 2 3 :: Pairs Intpair2 = Pr [] [3] :: Pairs [Int]pair3 = Pr [] [] :: Pairs [a]
equalPair :: Eq a => Pairs a -> BoolequalPair (Pr x y) = (x==y)
![Page 21: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/21.jpg)
Polymorphic algebraic types: lists
infixr 5 ::: -- same fixity and associativity as list cons :data List a = NilL | a ::: (List a)
deriving (Eq,Ord,Show,Read)A user-defined list type:List a instead of builtin [a]NillL instead of builtin []::: instead of builtin :
2+3 ::: 4+5 ::: NilL5 ::: (9 ::: NilL)
![Page 22: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/22.jpg)
Polymorphic algebraic types: trees
data Tree a = Nil | Node a (Tree a) (Tree a)deriving (Eq,Ord,Show,Read)
depthT :: Tree a -> IntegerdepthT Nil = 0depthT (Node n t1 t2) = 1 + max (depthT t1) (depthT t2)
collapse :: Tree a -> [a]collapse Nil = []collapse (Node x t1 t2)
= collapse t1 ++ [x] ++ collapse t2
![Page 23: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/23.jpg)
Polymorphic algebraic types: trees
collapse (Node 12(Node 34 Nil Nil) (Node 3 (Node 17 Nil Nil) Nil))
= [34, 12, 17, 3]
![Page 24: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/24.jpg)
Polymorphic algebraic types: trees
mapTree :: (a -> b) -> Tree a -> Tree bmapTree f Nil = NilmapTree f (Node x t1 t2)
= Node (f x) (mapTree f t1) (mapTree f t2)
![Page 25: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/25.jpg)
Polymorphic algebraic types: sum types
data Either a b = Left a | Right b
deriving (Eq,Ord,Read,Show)
eitherEG1 = Left "Duke of Prunes”
:: Either String Int
eitherEG2 = Right 33312
:: Either String Int
isLeft :: Either a b -> Bool
isLeft (Left _) = TrueisLeft (Right _) = False
![Page 26: Algebraic Types - GitLab · 2020. 3. 19. · dataExpr = Lit Integer| Add ExprExpr| Sub ExprExpr This describes an integer expression as something that one of: a literal, like 42;](https://reader035.fdocuments.net/reader035/viewer/2022071410/6105a8e343447a5af7291af5/html5/thumbnails/26.jpg)
Polymorphic algebraic types: sum types
either :: (a -> c) -> (b -> c) -> Either a b -> c
This is a higher-order function: takes functions as arguments.
Functions can also return functions as results!
either f g (Left x) = f xeither f g (Right y) = g y