Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 33 additions & 32 deletions haskell.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,6 @@ snd ("snd", "can't touch this", "da na na na") -- error! see function below
-- A simple function that takes two variables
add a b = a + b

-- Note that if you are using ghci (the Haskell interpreter)
-- You'll need to use `let`, i.e.
-- let add a b = a + b

-- Using the function
add 1 2 -- 3

Expand Down Expand Up @@ -336,7 +332,7 @@ distance :: Point -> Point -> Float
distance (Point x y) (Point x' y') = sqrt $ dx + dy
where dx = (x - x') ** 2
dy = (y - y') ** 2

-- Types can have multiple data constructors with arguments, too

data Name = Mononym String
Expand All @@ -345,7 +341,7 @@ data Name = Mononym String

-- To make things clearer we can use record syntax

data Point2D = CartesianPoint2D { x :: Float, y :: Float }
data Point2D = CartesianPoint2D { x :: Float, y :: Float }
| PolarPoint2D { r :: Float, theta :: Float }

myPoint = CartesianPoint2D { x = 7.0, y = 10.0 }
Expand All @@ -370,7 +366,7 @@ myPoint'2 = CartesianPoint2D 3.3 4.0

-- It's also useful to pattern match data constructors in `case` expressions

distanceFromOrigin x =
distanceFromOrigin x =
case x of (CartesianPoint2D x y) -> sqrt $ x ** 2 + y ** 2
(PolarPoint2D r _) -> r

Expand All @@ -387,8 +383,8 @@ Nothing -- of type `Maybe a` for any `a`

type String = [Char]

-- Unlike `data` types, type synonyms need no constructor, and can be used
-- anywhere a synonymous data type could be used. Say we have the
-- Unlike `data` types, type synonyms need no constructor, and can be used
-- anywhere a synonymous data type could be used. Say we have the
-- following type synonyms and items with the following type signatures

type Weight = Float
Expand All @@ -400,7 +396,7 @@ somePerson :: Person
someCircle :: Circle
distance :: Point -> Point -> Float

-- The following would compile and run without issue,
-- The following would compile and run without issue,
-- even though it does not make sense semantically,
-- because the type synonyms reduce to the same base types

Expand All @@ -412,50 +408,50 @@ distance (getMyHeightAndWeight somePerson) (findCenter someCircle)

-- Typeclasses are one way Haskell does polymorphism
-- They are similar to interfaces in other languages
-- A typeclass defines a set of functions that must
-- A typeclass defines a set of functions that must
-- work on any type that is in that typeclass.

-- The Eq typeclass is for types whose instances can
-- The Eq typeclass is for types whose instances can
-- be tested for equality with one another.

class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x /= y)
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x /= y)
x /= y = not (x == y)

-- This defines a typeclass that requires two functions, (==) and (/=)
-- It also declares that one function can be declared in terms of another
-- So it is enough that *either* the (==) function or the (/=) is defined
-- And the other will be 'filled in' based on the typeclass definition

-- To make a type a member of a type class, the instance keyword is used

instance Eq TrafficLight where
Red == Red = True
Green == Green = True
Yellow == Yellow = True
_ == _ = False
instance Eq TrafficLight where
Red == Red = True
Green == Green = True
Yellow == Yellow = True
_ == _ = False

-- Now we can use (==) and (/=) with TrafficLight objects

canProceedThrough :: TrafficLight -> Bool
canProceedThrough t = t /= Red

-- You can NOT create an instance definition for a type synonym

-- Functions can be written to take typeclasses with type parameters,
-- rather than types, assuming that the function only relies on
-- Functions can be written to take typeclasses with type parameters,
-- rather than types, assuming that the function only relies on
-- features of the typeclass

isEqual :: (Eq a) => a -> a -> Bool
isEqual x y = x == y

-- Note that x and y MUST be the same type, as they are both defined
-- as being of type parameter 'a'.
-- A typeclass does not state that different types in the typeclass can
-- A typeclass does not state that different types in the typeclass can
-- be mixed together.
-- So `isEqual Red 2` is invalid, even though 2 is an Int which is an
-- So `isEqual Red 2` is invalid, even though 2 is an Int which is an
-- instance of Eq, and Red is a TrafficLight which is also an instance of Eq

-- Other common typeclasses are:
Expand All @@ -466,11 +462,11 @@ isEqual x y = x == y
-- Enum for types that can be stepped through
-- Bounded for types with a maximum and minimum

-- Haskell can automatically make types part of Eq, Ord, Read, Show, Enum,
-- Haskell can automatically make types part of Eq, Ord, Read, Show, Enum,
-- and Bounded with the `deriving` keyword at the end of the type declaration

data Point = Point Float Float deriving (Eq, Read, Show)

-- In this case it is NOT necessary to create an 'instance' definition

----------------------------------------------------
Expand Down Expand Up @@ -559,14 +555,17 @@ main'' = do
----------------------------------------------------

-- Start the repl by typing `ghci`.
-- Now you can type in Haskell code. Any new values
-- need to be created with `let`:
-- Now you can type in Haskell code.

let foo = 5
> foo = 5
> foo
5

-- You can see the type of any value or expression with `:t`:

> :t foo
foo :: Num a => a
> :t +d foo
foo :: Integer

-- Operators, such as `+`, `:` and `$`, are functions.
Expand All @@ -584,6 +583,8 @@ class Num a where
-- Defined in ‘GHC.Num’
infixl 6 +

-- Type `:?` to get a list of all available commands.

-- You can also run any action of type `IO ()`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it ok that there are 2 comments like that in a row? It was puzzling to figure out where to place the "-- Type :? ..." line


> sayHello
Expand Down