Markdown format available here.
Haskell is a general purpose programming language, and can be used to build:
Haskell's main compiler is GHC.
--
for single line comment, {- -}
for block comments=
is used to declare the expression that is bound to the name on the left side (value definition)five = 5
increment n = n + 1
six = increment five
seven = increment (increment five)
incAndAdd x y = increment x + increment y
You can also define operators
x +- y = (x + x) - (y + y)
-- takes 3 arguments, so in this case N = 3
sum3 x y z = x + y + z
-- only supplies 2 arguments (K = 2), 0 and 1.
-- so newIncrement is a function that takes (N - K = 1) arguments
newIncrement = sum3 0 1
-- three is the value 3
three = newIncrement 2
let
or where
let [<definition>] in <expression>
is an expression and can be used anywherewhere
is special syntaxsumOf3 x y z =
let temp = x + y
in temp + z
-- or:
sumOf3 x y z = temp + z
where temp = x + y
type
to give a new alias to an existing type. They can be used interchangingly.type Nickname = String
We can give values a type signature using ::
myNickname :: Nickname
myNickname = "suppi"
data
|
to say "alternatively"data KnownColor -- the new type's name
= Red -- One possible value
| Blue
| Green
redColor :: KnownColor
redColor = Red
data
to define compound data of existing typesdata RGB
= MkRGB Int Int Int
{-
^ ^ ^ ^
| | | |
| | | +- This is the blue component
| | |
| | +----- This is the green component
| |
| +--------- This is the red component
|
+------------- This is called the value constructor, or "tag"
-}
magenta :: RGB
magenta = MkRGB 255 0 255
Red
, Blue
, Green
or RGB
) create a value of the typeRGB
), value constructors can be used as regular functions to build values of the typedata Color
= Red
| Blue
| Green
| RGB Int Int Int
blue :: Color
blue = Blue
magenta :: Color
magenta = RGB 255 0 255
data RGB = MkRGB
{ rgbRed :: Int
, rgbGreen :: Int
, rgbBlue :: Int
}
red :: RGB
red = MkRGB
{ rgbRed = 255
, rgbGreen = 0
, rgbBlue = 0
}
We use ->
to denote the type of a function from one type to another type
increment :: Int -> Int
increment n = n + 1
sum3 :: Int -> Int -> Int -> Int
sum3 x y z = x + y + z
supplyGreenAndBlue :: Int -> Int -> Color
supplyGreenAndBlue = RGB 100
->
is right associative, The function definitions from the previous slide will be parsed like this:
increment :: Int -> Int
increment n = n + 1
sum3 :: (Int -> (Int -> (Int -> Int)))
sum3 x y z = x + y + z
supplyGreenAndBlue :: (Int -> (Int -> Color))
supplyGreenAndBlue = RGB 100
This is why partial function application works.
-- I only take concrete `Int` values
identityInt :: Int -> Int
identityInt x = x
five :: Int
five = identityInt 5
-- `a` represents any one type
identity :: a -> a
identity x = x
seven :: Int
seven = identity 7
true :: Bool
true = identity True
const :: a -> b -> a
const x y = x
-- will fail because nothing in the type signature suggests that
-- `a` and `b` necessarily represent the same type
identity1 :: a -> b
identity1 x = x
-- will fail because we don't know if `a` is `Int`
identity2 :: a -> Int
identity2 x = x
-- will fail because we don't know if `a` is `Int`
identity3 :: Int -> a
identity3 x = x
compose :: (b -> c) -> (a -> b) -> a -> c
compose f g x = f (g x)
f . g = compose f g
->
in type signatures is right associativecompose :: ((b -> c) -> ((a -> b) -> (a -> c)))
compose f g x = f (g x)
As we saw earlier, Haskell is globally type inferred. We can remove almost all type signatures and Haskell will choose the most general type signature for us.
data IntList
= EndOfIntList
| ValAndNext Int IntList
-- the list [1,2,3]
list123 :: IntList
list123 = ValAndNext 1 (ValAndNext 2 (ValAndNext 3 EndOfList))
data IntTree
= Leaf
| Node
IntTree -- Left subtree
Int -- Node value
IntTree -- Right subtree
-- 2
-- / \
-- 1 3
-- /
-- 1
tree1123 :: IntTree
tree1123 =
Node
(Node (Node Leaf 1 Leaf) 1 Leaf)
2
(Node Leaf 3 Leaf)
Int
or Bool
like in the previous slide-- a value of type a or nothing
data Maybe a
= Just a
| Nothing
-- a value of type a or a value of type b
data Either a b
= Left a
| Right b
-- A linked list of `a`s
-- Note: there's also a built in syntax in Haskell for linked lists
data List a -- [a] -- special syntax for a linked list of a generic type `a`
= Nil -- [] -- special syntax for the empty list
| Cons a (List a) -- x : xs -- special operator for constructing a list
case <expr> of
<pattern1> -> <result1>
<pattern2> -> <result2>
...
<patternN> -> <resultN>
myIf :: Bool -> a -> a -> a
myIf test trueBranch falseBranch =
case test of
True -> trueBranch
False -> falseBranch
factorial :: Int -> Int
factorial num =
case num of
0 -> 1
n -> n * factorial (n - 1)
_
means match anythingcolorName :: Color -> String
colorName color =
case color of
Red -> "red"
Green -> "green"
Blue -> "blue"
RGB 255 0 255 -> "magenta"
RGB _ 255 _ -> "well it has a lot of green in it"
_ -> "i don't know this color"
<-
is used to bind the result of an IO action to a variable when using do notationlet
is used to bind an expression to a namemain :: IO ()
main = do
putStrLn "Hello!"
putStrLn "What is your name?"
result <- getLine
putStrLn ("Nice to meet you, " ++ result)
putStrLn "Here is the result of 1+1: "
let calculation = factorial 100 -- note that when using do notation we don't need to use `in`
putStrLn (show calculation)
putStrLn "Bye!"