8. Overview
Some examples in this chapter assume you are familiar with Data.Set
and Data.Map. You should ignore them on a first reading if they are
unfamiliar.
-
Types must start with capital letters. A type can be called
Dinosaurbut notdinosaur. -
Type synonyms, also known as type aliases.
type BasicPoint = (Float, Float) -
Use Data to create new data types. Here is a Point data type:
data Point = Point Float Float getX (Point x y) = x -
Use
derivingto have an automatic simple output format and equality operation.data Point = Point Float Float deriving (Show, Eq) -
Constant types represent choices but do not have any more information inside them. Usually combined with choices using
|, which is read “or”.data WYClass = Regular | Honors | AP deriving (Show, Eq) -
Choices can have different amounts of data.
data Lightswitch = Off | On | Dimmer Float deriving (Show, Eq) -
Named fields create functions that give the values in each field.
data Circle = Circle { center :: Point2D, radius :: Float } deriving (Show, Eq)Named fields are like a Racket struct or Python’s
@dataclassor perhaps justnamedtuple. -
Use named fields when creating variables. Using
{...}after the name of a variable makes a copy and only changes the fields listed.p = Point2D 20.0 50.0 c = Circle {center=p, radius=16.0} -- Note: created q = p{x=30.0} -- new x, same y=50 that pp had d = c{center=q} -- new center, same radius as c -
Regardless of how you defined the record, you can pattern match partial or whole objects. a f1 (Circle center radius) = center f2 Circle{center=c, radius=r} = c f3 Circle{center=c} = c
-
Pattern guards. It turns out you can pattern match inside a guard, but it looks a little strange.
power :: Float -> Lightswitch -> Float power maxpower sw | Off <- sw = 0.0 | On <- sw = maxpower | Dimmer amount <- sw = maxpower * amount / 100 -
Danger: if the same field names are used in different records, enable the extension
DisambiguateRecordFieldsby adding the following code at the start of your file.{-# LANGUAGE DisambiguateRecordFields #-} -
Either a b = Left a | Right b. Read about it in the chapter.
Typeclasses 102
This part of the chapter contains some challenging material.
-
Making your new data type an instance of existing typeclasses, like
Eq,Show, orOrd. -
Creating a new typeclass using
class (MyThing a) where ... -
Building on existing types using
instance (Eq a) => Eq (Maybe a) where… -
(
class YesNoandinstance YesNo [a] where ...) Making your own typeclass. -
Functor: Yikes, start reading the text!! Memorize the typeclass rules for Functor. -
Discovering kinds using
:k. Abstract! Read. -
The note at the end: “you don’t have to understand everything we did here…”. Take that seriously.
Explanations: type vs data
-
typeThese are just alternative names for the type on the right side of the equals sign. If a function that has an output of a
BasicPoint, that output can be used as an input that is declared to require(Float,Float). These types are considered the weakest to use. -
dataThese are stronger types because you cannot use a
Pointin a place where a type with a different name is required, even if both contain two Floats. -
newtypeThese special, efficient
datastatements that can only contain one type of thing. Not taught.