Abstract Types, Algebraic Types, and Type Classes

Similar documents
Informatics 1 Functional Programming Lectures 13 and 14 Monday 11 and Tuesday 12 November Type Classes. Don Sannella University of Edinburgh

Informatics 1 Functional Programming Lecture 12. Data Abstraction. Don Sannella University of Edinburgh

CS 320: Concepts of Programming Languages

Informatics 1 Functional Programming Lecture 9. Algebraic Data Types. Don Sannella University of Edinburgh

Course year Typeclasses and their instances

Informatics 1 Functional Programming Lecture 11. Data Representation. Don Sannella University of Edinburgh

CSc 372. Comparative Programming Languages. 18 : Haskell Type Classes. Department of Computer Science University of Arizona

Haskell Types, Classes, and Functions, Currying, and Polymorphism

Practical Haskell. An introduction to functional programming. July 21, Practical Haskell. Juan Pedro Villa-Isaza. Introduction.

Haskell 101. (Version 1 (July 18, 2012)) Juan Pedro Villa Isaza

An introduction to functional programming. July 23, 2010

More fun with recursion

(ii) Define a function ulh that takes a list xs, and pairs each element with all other elements in xs.

Programming Languages Fall 2013

Informatics 1 Functional Programming Lecture 5. Function properties. Don Sannella University of Edinburgh

Advanced features of Functional Programming (Haskell)

Type system. Type theory. Haskell type system. EDAN40: Functional Programming Types and Type Classes (revisited)

EDAF40. 2nd June :00-19:00. WRITE ONLY ON ONE SIDE OF THE PAPER - the exams will be scanned in and only the front/ odd pages will be read.

Type Classes in Haskell Tom Schrijvers. Leuven Haskell User Group

Functional Programming TDA 452, DIT 142

CS 360: Programming Languages Lecture 10: Introduction to Haskell

Functional Programming TDA 452, DIT 142

PROGRAMMING IN HASKELL. Chapter 5 - List Comprehensions

Haskell An Introduction

User-Defined Algebraic Data Types

CSCE 314 Programming Languages

Overview. Declarative Languages D7012E. Overloading. Overloading Polymorphism Subtyping

Standard prelude. Appendix A. A.1 Classes

1 The number systems in Haskell 98

Overloading, Type Classes, and Algebraic Datatypes

A tour of the Haskell Prelude

A general introduction to Functional Programming using Haskell

CS 360: Programming Languages Lecture 12: More Haskell

Solution sheet 1. Introduction. Exercise 1 - Types of values. Exercise 2 - Constructors

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

INTRODUCTION TO HASKELL

Module Title: Informatics 1 Functional Programming (first sitting) Exam Diet (Dec/April/Aug): December 2014 Brief notes on answers:

Basic types and definitions. Chapter 3 of Thompson

Informatics 1 Functional Programming Lecture 4. Lists and Recursion. Don Sannella University of Edinburgh

Custom Types. Outline. COMP105 Lecture 19. Today Creating our own types The type keyword The data keyword Records

Logic - CM0845 Introduction to Haskell

CS 457/557: Functional Languages

Lecture 1 August 9, 2017

Informatics 1 Functional Programming 19 Tuesday 23 November IO and Monads. Philip Wadler University of Edinburgh

Recursion and Induction: Haskell; Primitive Data Types; Writing Function Definitions

Higher Order Functions in Haskell

Functional Programming for Logicians - Lecture 1

Introduction to Programming and 4Algorithms Abstract Types. Uwe R. Zimmer - The Australian National University

FUNCTIONAL PROGRAMMING NO.9 TYPE AND CLASS. Tatsuya Hagino

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

CS 320: Concepts of Programming Languages

Type Processing by Constraint Reasoning

An introduction introduction to functional functional programming programming using usin Haskell

Instances for Free* Neil Mitchell (* Postage and packaging charges may apply)

CSE 3302 Programming Languages Lecture 8: Functional Programming

Informatics 1 Functional Programming Lecture 7. Map, filter, fold. Don Sannella University of Edinburgh

CSc 372. Comparative Programming Languages. 8 : Haskell Function Examples. Department of Computer Science University of Arizona

CSci 450: Org. of Programming Languages Overloading and Type Classes

INTRODUCTION TO FUNCTIONAL PROGRAMMING

Advances in Programming Languages

According to Larry Wall (designer of PERL): a language by geniuses! for geniuses. Lecture 7: Haskell. Haskell 98. Haskell (cont) - Type-safe!

Functional Programming Mid-term exam Tuesday 3/10/2017

Haskell Overview II (2A) Young Won Lim 8/9/16

Haskell Overview III (3A) Young Won Lim 10/4/16

Lecture 2: List algorithms using recursion and list comprehensions

Haskell Making Our Own Types and Typeclasses

CSC312 Principles of Programming Languages : Functional Programming Language. Copyright 2006 The McGraw-Hill Companies, Inc.

CS 440: Programming Languages and Translators, Spring 2019 Mon

Algebraic Types. Chapter 14 of Thompson

Haskell: Lists. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Friday, February 24, Glenn G.

CSCE 314 Programming Languages

Principles of Programming Languages

Informatics 1 Functional Programming Lectures 15 and 16. IO and Monads. Don Sannella University of Edinburgh

Programming Paradigms and Languages Introduction to Haskell. dr Robert Kowalczyk WMiI UŁ

Thoughts on Assignment 4 Haskell: Flow of Control

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

CS 457/557: Functional Languages

Introduction to SML Basic Types, Tuples, Lists, Trees and Higher-Order Functions

Programming in Haskell Aug-Nov 2015

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Haskell Functions

Functional Programming in Haskell Part I : Basics

UNIVERSITY OF EDINBURGH COLLEGE OF SCIENCE AND ENGINEERING SCHOOL OF INFORMATICS INFR08013 INFORMATICS 1 - FUNCTIONAL PROGRAMMING

Haskell Overview II (2A) Young Won Lim 8/23/16

CSc 372 Comparative Programming Languages

UNIVERSITY OF EDINBURGH COLLEGE OF SCIENCE AND ENGINEERING SCHOOL OF INFORMATICS INFR08013 INFORMATICS 1 - FUNCTIONAL PROGRAMMING

GADTs. GADTs in Haskell

Testing. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 2. [Faculty of Science Information and Computing Sciences]

Haskell Introduction Lists Other Structures Data Structures. Haskell Introduction. Mark Snyder

Haskell Revision and Exercises

The Monad.Reader Issue 20

Set Haskell Exercises

How does ML deal with +?

Shell CSCE 314 TAMU. Functions continued

Lecture 19: Functions, Types and Data Structures in Haskell

Haskell Programs. Haskell Fundamentals. What are Types? Some Very Basic Types. Types are very important in Haskell:

Lecture 4: Higher Order Functions

Monads seen so far: IO vs Gen

Advanced Type System Features Tom Schrijvers. Leuven Haskell User Group

Introduction to Haskell

Chapter 15. Functional Programming. Topics. Currying. Currying: example. Currying: example. Reduction

Transcription:

Informatics 1 Functional Programming Lectures 13 and 14 Monday 9 and Tuesday 10 November 2009 Abstract Types, Algebraic Types, and Type Classes Philip Wadler University of Edinburgh

Reminders Tutorial groups for students requiring extra help Contact Tamise Totterdell at ITO to join Study group for students desiring more challenging work Use the newsgroups! Mock exam next week, sign up via ITO

Part I Abstract Data Types: Sets implemented as lists

Sets as lists definition (1) module SetList(Set,element,nil,insert,delete, set,allset,subset,equal,showset) where data Set a = MkSet [a] element :: Eq a => a -> Set a -> Bool element x (MkSet xs) = elem x xs nil :: Set a nil = MkSet [] insert :: a -> Set a -> Set a insert x (MkSet xs) = MkSet (x:xs) delete :: Eq a => a -> Set a -> Set a delete x (MkSet xs) = MkSet [ y y <- xs, x /= y ]

Sets as lists definition (2) set :: [a] -> Set a set xs = MkSet xs allset :: (a -> Bool) -> Set a -> Bool allset p (MkSet xs) = all p xs subset :: Eq a => Set a -> Set a -> Bool s subset t = allset (\x -> element x t) s equal :: Eq a => Set a -> Set a -> Bool s equal t = s subset t && t subset s showset (MkSet xs) = "MkSet " ++ show xs

Sets as lists use (1) module MainList where import Test.QuickCheck import SetList s0 :: Set Int s0 = set [2,7,1,8,2,8] prop_show :: Bool prop_show = showset s0 == "MkSet [2,7,1,8,2,8]"

Sets as lists use (2) prop_insert :: Int -> Int -> [Int] -> Bool prop_insert x y xs = element x (insert y s) == (x == y element x s) where s = set xs prop_delete :: Int -> Int -> [Int] -> Bool prop_delete x y xs = element x (delete y s) == (element x s && x /= y) where s = set xs prop_insert_delete :: Int -> [Int] -> Property prop_insert_delete x xs = not (element x s) ==> s equal delete x (insert x s) where s = set xs

Sets as lists sample run (1) [comrie]wadler: ghci MainList.hs GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim... linking... done. Loading package integer... linking... done. Loading package base... linking... done. [1 of 2] Compiling SetList ( SetList.hs, interpreted ) [2 of 2] Compiling MainList ( MainList.hs, interpreted ) Ok, modules loaded: MainList, SetList. *MainList> element 2 s0 True *MainList> element 3 s0 False *MainList> s0 No instance for (Show (Set Int)) *MainList> head s0 <interactive>:1:5: Couldn t match expected type [a] against inferred type Se

Sets as lists sample run (2) *MainList> showset s0 "MkSet [2,7,1,8,2,8]" *MainList> quickcheck prop_insert OK, passed 100 tests. *MainList> quickcheck prop_delete OK, passed 100 tests. *MainList> quickcheck prop_insert_delete OK, passed 100 tests.

Part II Sets, implemented as trees

Sets as trees definition (1) module SetTree(Set,element,nil,insert,delete, set,allset,subset,equal,showset) where data Set a = Nil Node (Set a) a (Set a) element :: Ord a => a -> Set a -> Bool element x Nil = False element x (Node l y r) x == y = True x < y = element x l x > y = element x r

Sets as trees definition (2) nil :: Set a nil = Nil insert :: Ord a => a -> Set a -> Set a insert x Nil = Node Nil x Nil insert x (Node l y r) x == y = Node l y r x < y = Node (insert x l) y r x > y = Node l y (insert x r)

Sets as trees definition (3) set :: Ord a => [a] -> Set a set = foldr insert nil allset :: (a -> Bool) -> Set a -> Bool allset p s = all p (list s) where list :: Set a -> [a] list Nil = [] list (Node l x r) = list l ++ [x] ++ list r subset :: Ord a => Set a -> Set a -> Bool s subset t = allset (\x -> element x t) s equal :: Ord a => Set a -> Set a -> Bool s equal t = s subset t && t subset s

Sets as trees definition (4) showset :: Show a => Set a -> String showset Nil = "Nil" showset (Node l x r) = "(Node " ++ showset l ++ " " ++ show x ++ " " ++ showset r ++ ")"

Sets as trees definition (5) delete :: Ord a => a -> Set a -> Set a delete x Nil = Nil delete x (Node l y r) x == y = join l r x < y = Node (delete x l) y r x > y = Node l y (delete x r) join :: Ord a => Set a -> Set a -> Set a join l Nil = l join l r = Node l x (delete x r) where x = smallest r smallest :: Ord a => Set a -> a smallest (Node Nil y r) = y smallest (Node l y r) = smallest l

Sets as trees use (1) module MainTree where import Test.QuickCheck import SetTree s0 :: Set Int s0 = set [2,7,1,8,2,8] prop_show :: Bool prop_show = showset s0 == "(Node (Node (Node Nil 1 Nil) 2 (Node Nil 7 Nil)) 8 Nil)" -- set [2,7,1,8,2,8] == -- insert 2 (insert 7 (insert 1 -- insert 8 (insert 2 (insert 8 nil))))

Sets as trees use (2) prop_insert :: Int -> Int -> [Int] -> Bool prop_insert x y xs = element x (insert y s) == (x == y element x s) where s = set xs prop_delete :: Int -> Int -> [Int] -> Bool prop_delete x y xs = element x (delete y s) == (element x s && x /= y) where s = set xs prop_insert_delete :: Int -> [Int] -> Property prop_insert_delete x xs = not (element x s) ==> equalset s (delete x (insert x s)) where s = set xs

Sets as trees sample run (1) [comrie]wadler: ghci MainList.hs GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim... linking... done. Loading package integer... linking... done. Loading package base... linking... done. [1 of 2] Compiling SetList ( SetList.hs, interpreted ) [2 of 2] Compiling MainList ( MainList.hs, interpreted ) Ok, modules loaded: MainList, SetList. *MainList> element 2 s0 True *MainList> element 3 s0 False *MainList> s0 No instance for (Show (Set Int)) *MainList> head s0 <interactive>:1:5: Couldn t match expected type [a] against inferred type Se

Sets as trees sample run (2) *MainList> showset s0 "(Node (Node (Node Nil 1 Nil) 2 (Node Nil 7 Nil)) 8 Nil)" (Node (Node (Node Nil 1 Nil) 2 (Node Nil 7 Nil)) 8 Nil)"

Sets as trees sample run (3) *MainList> quickcheck prop_insert OK, passed 100 tests. *MainList> quickcheck prop_delete OK, passed 100 tests. *MainList> quickcheck prop_insert_delete OK, passed 100 tests.

Part III Type classes

Element elem :: Eq a => a -> [a] -> Bool -- comprehension elem x ys = or [ x == y y <- ys ] -- recursion elem x [] = False elem x (y:ys) = x == y elem x ys -- higher-order elem x ys = foldr ( ) False (map (x ==) ys)

Using element *Main> elem 1 [2,3,4] False *Main> elem o "word" True *Main> elem (1, o ) [(0, w ),(1, o ),(2, r ),(3, d )] True *Main> elem "word" ["list","of","word"] True *Main> elem (\x -> x) [(\x -> -x), (\x -> -(-x))] No instance for (Eq (a -> a))

Equality type class class Eq a where (==) :: a -> a -> Bool instance Eq Int where (==) = eqint instance Eq Char where x == y = ord x == ord y instance (Eq a, Eq b) => Eq (a,b) where (u,v) == (x,y) = (u == x) && (v == y) instance Eq a => Eq [a] where [] == [] = True [] == y:ys = False x:xs == [] = False x:xs == y:ys = (x == y) && (xs == ys)

Element, translation data EqDict a = EqD (a -> a -> Bool) eq :: EqDict a -> a -> a -> Bool eq (EqDict f) = f elem :: EqD a -> a -> [a] -> Bool -- comprehension elem d x ys = or [ eq d x y y <- ys ] -- recursion elem d x [] = False elem d x (y:ys) = eq d x y elem x ys -- higher-order elem d x ys = foldr ( ) False (map (eq d x) ys)

Type classes, translation dint :: EqDict Int dint = EqD eqint dchar :: EqDict Char dchar = EqD f where f x y = eq dint (ord x) (ord y) dpair :: (EqDict a, EqDict b) -> EqDict (a,b) dpair (da,db) = EqD f where f (u,v) (x,y) = eq da u x && eq db v y dlist :: EqDict a -> EqDict [a] dlist d = EqD f where f [] [] = True f [] (y:ys) = False f (x:xs) [] = False f (x:xs) (y:ys) = eq d x y && eq (dlist d) xs ys

Using element, translation *Main> elem dint 1 [2,3,4] False *Main> elem dchar o "word" True *Main> elem (dpair dint dchar) (1, o ) [(0, w ),(1, o )] True *Main> elem (dlist dchar) "word" ["list","of","word"] True Haskell uses types to write code for you!

Part IV Boolean

Type classes class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool x /= y = not (x == y) class (Eq a) => Ord a where (<) :: a -> a -> Bool (<=) :: a -> a -> Bool (>) :: a -> a -> Bool (>=) :: a -> a -> Bool x <= y = x < y x == y x > y = y < x x >= y = y <= x class Show a where show :: a -> String

Instances for boolean instance Eq Bool where False == False = True True == True = True _ == _ = False instance Ord Bool where False < True = True _ < _ = False instance Show Bool where show False = "False" show True = "True"

Boolean with deriving clause data Bool = False True deriving (Eq, Ord, Show) Haskell uses types to write code for you!

Part V Sets, revisited

Sets as trees, revisited data Set a = Nil Node (Set a) a (Set a) instance Ord a => Eq (Set a) where s == t = s subset t && t subset s instance Show a => Show (Set a) where show Nil = "Nil" show (Node l x r) = "(Node " ++ show l ++ " " ++ show x ++ " " ++ show r ++ ")"

Sets as trees, revisited, revisited data Set a = Nil Node (Set a) a (Set a) deriving (Show) instance Ord a => Eq (Set a) where s == t = s subset t && t subset s

Part VI Tuples and lists

Tuples data (a,b) = (a,b) deriving (Eq,Ord,Show) instance (Eq a, Eq b) => Eq (a,b) where (x,y) == (x,y ) = x == x && y == y instance (Ord a, Ord b) => Ord (a,b) where (x,y) < (x,y ) = x < x (x == x && y < y ) instance (Show a, Show b) => Show (a,b) where show (x,y) = "(" ++ show x ++ "," ++ show y ++ ")"

Lists data [a] = [] a:[a] deriving (Eq,Ord,Show) instance Eq a => Eq [a] where [] == [] = True [] == y:ys = False x:xs == [] = False x:xs == y:ys = x == y && xs == ys instance Ord a => Ord [a] where [] < [] = False [] < y:ys = True x:xs < [] = False x:xs < y:ys = x < y (x == y && xs < ys) instance Show a => Show [a] where show [] = "[]" show (x:xs) = "[" ++ showsep x xs ++ "]" where showsep x [] = show x showsep x (y:ys) = show x ++ "," ++ showsep y ys

Part VII Equality over functions

Equality over functions class Small a where forall :: (a -> Bool) -> Bool instance Small Char where forall p = and [ p x x <- [ \000.. \255 ] ] instance Small Bool where forall p = and [ p x x <- [False, True] ] instance (Small a, Small b) => Small (a,b) where forall p = forall (\x -> (forall (\y -> p (x,y)))) instance (Small a, Eq b) => Eq (a -> b) where f == g = forall (\x -> f x == g x) *Main elem (\x -> x) [(\x -> not x), (\x -> not (not x))] True

Part VIII Seasons

Seasons data Season = Winter Spring Summer Fall next :: Season -> Season next Winter = Spring next Spring = Summer next Summer = Fall next Fall = Winter warm :: Season -> Bool warm Winter = False warm Spring = True warm Summer = True warm Fall = True

Seasons with deriving clause data Season = Winter Spring Summer Fall deriving (Eq, Ord, Show, Enum)

instance Eq Seasons where Winter == Winter = True Spring == Spring = True Summer == Summer = True Fall == Fall = True _ == _ = False instance Ord Seasons where Winter < Spring = True Winter < Summer = True Winter < Fall = True Spring < Summer = True Spring < Fall = True Summer < Fall = True _ < _ = False instance Show Seasons where show Winter = "Winter" show Spring = "Spring" show Summer = "Summer" show Fall = "Fall"

The Enum class class Enum a where succ, pred :: a -> a toenum :: Int -> a fromenum :: a -> Int enumfrom :: a -> [a] -- [x..] enumfromto :: a -> a -> [a] -- [x..y] enumfromthen :: a -> a -> [a] -- [x,y..] enumfromthento :: a -> a -> a -> [a] -- [x,y..z] succ x = toenum (fromenum x + 1) pred x = toenum (fromenum x - 1) enumfrom x = map toenum [fromenum x..] enumfromto x y = map toenum [fromenum x.. fromenum y] enumfromthen x y = map toenum [fromenum x, fromenum y..] enumfromthento x y z = map toenum [fromenum x, fromenum y.. fromenum z]

Syntactic sugar -- [x..] = enumfrom x -- [x..y] = enumfromto x y -- [x,y..] = enumfromthen x y -- [x,y..z] = enumfromthento x y z instance Enum Int where toenum x = x fromenum x = x succ x = x+1 pred x = x-1 enumfrom x = iterate (+1) x enumfromto x y = takewhile (<= y) (iterate (+1) x) enumfromthen x y = iterate (+(y-x)) x enumfromthento x y z = takewhile (<= z) (iterate (+(y-x)) x) iterate :: (a -> a) -> a -> [a] iterate f x = x : iterate f (f x)

Derived instance instance Enum Seasons where fromenum Winter = 0 fromenum Spring = 1 fromenum Summer = 2 fromenum Fall = 3 toenum 0 = Winter toenum 1 = Spring toenum 2 = Summer toenum 3 = Fall

Seasons, revisited next :: Season -> Season next x = toenum ((fromenum x + 1) mod 4) warm :: Season -> Bool warm x = x elem [Spring..Fall] -- [Spring..Fall] = [Spring, Summer, Fall]

Part IX Shape

Shape type Radius = Float type Width = Float type Height = Float data Shape = Circle Radius Rect Width Height deriving (Eq, Ord, Show) area :: Shape -> Float area (Circle r) = pi * rˆ2 area (Rect w h) = w * h

Derived instances instance Eq Shape where Circle r == Circle r = r == r Rect w h == Rect w h = w == w && h == h _ == _ = False instance Ord Shape where Circle r < Circle r = r < r Circle r < Rect w h = True Rect w h < Rect w h = w < w (w == w && h < h ) _ < _ = False instance Show Shape where show (Circle r) = "Circle " ++ shown r show (Radius w h) = "Radius " ++ shown w ++ " " ++ shown h shown :: (Num a) => a -> String shown x x >= 0 = show x otherwise = "(" ++ show x ++ ")"

Part X Expressions

Expression Trees data Exp = Lit Int Exp :+: Exp Exp :*: Exp deriving (Eq, Ord, Show) eval :: Exp -> Int eval (Lit n) = n eval (e :+: f) = eval e + eval f eval (e :*: f) = eval e * eval f *Main> eval (Lit 2 :+: (Lit 3 :*: Lit 3)) 11 *Main> eval ((Lit 2 :+: Lit 3) :*: Lit 3) 15

Derived instances instance Eq Exp where Lit n == Lit n = n == n e :+: f == e :+: f = e == e && f == f e :*: f == e :*: f = e == e && f == f _ == _ = False instance Ord Exp where Lit n < Lit n = n < n Lit n < e :+: f = True Lit n < e :*: f = True e :+: f < e :+: f = e < e (e == e && f < f ) e :+: f < e :*: f = True e :*: f < e :*: f = e < e (e == e && f < f ) instance Show Exp where show (Lit n) = "Lit " ++ shown n show (e :+: f) = "(" ++ show e ++ ":+:" ++ show f ++ ")" show (e :*: f) = "(" ++ show e ++ ":*:" ++ show f ++ ")"

Part XI Numbers

Numerical classes class (Eq a, Show a) => Num a where (+),(-),(*) :: a -> a -> a negate :: a -> a frominteger :: Integer -> a class (Num a) => Fractional a where (/) :: a -> a -> a recip :: a -> a fromrational :: Rational -> a recip x = 1/x class (Num a, Ord a) => Real a where torational :: a -> Rational class (Real a, Enum a) => Integral a where div, mod :: a -> a -> a tointeger :: a -> Integer

A built-in numerical type instance Num Float where (+) = builtinaddfloat (-) = builtinsubtractfloat (*) = builtinmultiplyfloat negate = builtinnegatefloat frominteger = builtinfromintegerfloat instance Fractional Float where (/) = builtindividefloat fromrational = builtinfromrationalfloat

A user-defined numerical type data Point = Pnt Float Float scalar :: Float -> Point scalar x = Pnt x x instance Num Point where Pnt x y + Pnt x y = Pnt (x+x ) (y+y ) Pnt x y - Pnt x y = Pnt (x-x ) (y-y ) Pnt x y * Pnt x y = Pnt (x*x ) (y*y ) negate (Pnt x y) = Pnt (-x) (-y) frominteger z = scalar (frominteger z) instance Fractional Point where Pnt x y / Pnt x y = Pnt (x/x ) (y/y ) fromrational z = scalar (fromrational z)

Points instance Eq Point where Pnt x y == Pnt x y = x == x && y == y instance Ord Point where Pnt x y < Pnt x y = x < x && y < y glb,lub :: Point -> Point -> Point Pnt x y glb Pnt x y = Pnt (x min x ) (y min y ) Pnt x y lub Pnt x y = Pnt (x max x ) (y max y )