Haskell Notes
defining functions
Haskell is a functional programming language. This basically means functions are first-class citizens. Let’s look at how to define a function.
add x y = x + y
add 1 2
3
functions are partial
In haskell, functions can be partially applied (applied with less arguments than defined)
add1 = add 1
add1 2
3
If we apply
with only one argument 1
add
, then we get a new function 1
1
which takes one argument.1
add1
infix and prefix
In haskell, infix functions (i.e. operators in other languages) and prefix functions are treated alike. They can be transformed into each other using
and 1
()
1
` `
-- infix -> prefix
1 + 2
3
(+) 1 2
3
-- prefix -> infix
myadd x y = x + y
1 `add` 2
3
let
The
statement provides syntactic sugar for 1
let
.1
"defining variables"
let x = 1
y = 2
add x y = x + y
in 1 + (add x y)
4
I put quotes around “defining variables” because x and y are not variables in other languages’ sense. Instead, they are just bindings local to the statement, which is somewhat unique to haskell. The let statement can also define functions.
closures/anonymous functions/lambdas
-- the follwing are equivalent:
add x y = x + y
add = \x y -> x + y
-- the follwing are equivalent:
add 1
\x add 1 x
lazy evaluation
-- the cycle function
take 10 (cycle [1,2,3])
[1,2,3,1,2,3,1,2,3,1]
-- one way to define the cycle function
cycle x = x ++ cycle x
generates an infinite list 1
cycle [1,2,3]
. Because Haskell is lazy, applying 1
1,2,3,1,2,3,1,2,3,...
to that list actually yields an finite list ``.1
take 10
type, type class
a type class is like a Java interface a type, a type is like a concrete Java class implementing an interface,
We use
to define a type.1
data
data Point = Point Int Int deriving Show
Point 1 2
The
typeclass defines a 1
Show
function which is used to print a data type. We can redefine this function as follows:1
show
data Point = Point Int Int
instance Show Point where
show (Point x y) = (show x) ++ "," ++ (show y)
type constructor
data Maybe a = Nothing | Just a
We call
a type constructor. Depending on the type of 1
Maybe
, this constructor can end up creating a Maybe Int, Maybe Car, or Nothing.1
a
functors
The
is an instance of 1
Maybe
type class. A 1
Functor
is simply something that you can map on.1
Functor
class Functor f where
fmap :: (a -> b) -> f a -> f b
-- lists are instances of functors
instance Functor [] where
fmap = map
-- maybe's are instances of functors
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap f Nothing = Nothing
fmap inc (Just 1)
It’s easy (or not so easy) to see that
and 1
Lists
are instances of 1
Maybe's
.1
Functors
pattern matching and erlang-like case statements
As seen above, pattern matching can be used in function arguments. It can also be used in
statements and 1
case
statements.1
let
let (Point x y) = (Point 1 2) in
x + y
head' :: [a] -> a
head' xs = case xs of [] -> error "No head for empty lists!"
(x:_) -> x
:kind :info :type
shows type information on types and type classes1
:kind
shows detailed information on types and type classes.1
:info
shows type for instances of types, and type classes for types.1
:type