Want to learn more? Take my Intro to Haskell course at
enginehere.com/courses/intro-to-haskell-etrepum
(In order of preference)
λ>
is the interpreter prompt.--
are comments.
|
|
…
replaced by the expression you want to evaluate:main = print (…)
|
|
function arg
.λ> even 10
True
λ> negate 4
-4
λ> negate 1 + 10
9
λ> max 4 5
5
λ> True && not (False || True)
False
|
|
module Prelude
result3 ^ 1337
.mod
function for this, try evaluating these expressions:λ> mod 1234 100
…
λ> 1234 `mod` 10
…
theyAreWrittenLikeThis
.λ> let x = 10 in x * x
100
λ> let { x = 10; y = 2 } in x * y
20
λ> let { x = 2 * y; y = 40 } in x * y
3200
λ> let { x = undefined; y = 2 } in y
2
λ> let { r = 2; area = pi * r * r } in area
12.566370614359172
let
expression with variables r
and circumference
that evaluates to the circumference of a circle with that radius-- this is far more common than lambda syntax
λ> let inc x = x + 1 in inc 10
11
λ> let add x y = x + y in add 1 2
3
-- parentheses only used for clarity here
λ> let inc = (\x -> x + 1) in inc 10
11
λ> let add = (\x -> (\y -> x + y)) in add 1 2
5
circumference
that takes an argument r
and evaluates to the circumference of a circle with the given radius.\lambda ->
syntax:
and []
λ> [1, 2, 3, 4]
[1,2,3,4]
λ> 1 : 2 : 3 : 4 : []
[1,2,3,4]
λ> (:) 1 ((:) 2 ((:) 3 ((:) 4 [])))
[1,2,3,4]
λ> ['a', 'b', 'c', 'd']
"abcd"
λ> 'a' : 'b' : "cd"
"abcd"
λ> [True, 1 == 0, 1 > 0]
[True,False,True]
λ> [1, 2] ++ [3, 4]
[1,2,3,4]
[Char]
showNumber
that given a number, evaluates to the string "Your number is: " with the given number as a string appended to it.showNumber 10
would evaluate to"Your number is: 10"
show
function to do this, show 10
evaluates to "10"
fib x =
if x > 1 then fib (x - 1) + fib (x - 2) else x
fib x =
if x > 1
then fib (x - 1) + fib (x - 2)
else x
fac
that given a positive integer, evalues to the factorial of that number.fac n = n * (n - 1) * (n - 2) * … * 2 * 1
fib x =
case x of {0 -> 0; 1 -> 1; _ -> fib (x-1) + fib (x-2)}
fib x = case x of
0 -> 0
1 -> 1
_ -> fib (x - 1) + fib (x - 2)
fib 0 = 0
fib 1 = 1
fib x = fib (x - 1) + fib (x - 2)
lastElem [] = error "empty list"
lastElem (x : []) = x
lastElem (_ : xs) = lastElem xs
lastElem [] = error "empty list"
lastElem [x] = x
lastElem (_ : xs) = lastElem xs
firstElem
that evaluates to the first element of the given list, or error "empty list"
if given an empty list.firstElem [1,2,3] == 1
nth
that evaluates to the nth element of a list (with zero based indexing), or error "index too large"
if the list is too short.nth 1 [1,2,3] == 2
otherwise
is equivalent to True
evens xs = case xs of
[] -> []
(x : xs') | x `rem` 2 == 0 -> x : evens xs'
| otherwise -> evens xs'
evens [] = []
evens (x:xs)
| x `rem` 2 == 0 = x : evens xs
| otherwise = evens xs
select
which returns the list elements that match the given predicate.select (>5) [2,4,6,8,10] == [6,8,10]
foldr
is a right fold, which can be used to implement many other functions on lists:
with k
and []
with z
foldr k z [] = z
foldr k z (x:xs) = x `k` foldr k z xs
map
is a commonly used list function that can be expressed in terms of foldr
map (+1) [1,2,3,4] == [2,3,4,5]
map f xs = foldr (\x acc -> f x : acc) [] xs
map f xs = foldr (\x acc -> f x : acc) [] xs
-- eta-reduction, remove xs from both sides
map f = foldr (\x acc -> (f x : acc)) []
-- rewrite in prefix form
map f = foldr (\x acc -> (:) (f x) acc)) []
-- eta-reduction of inner function
map f = foldr (\x -> (:) (f x))) []
-- reduce inner function further with .
map f = foldr ((:) . f) []
map f = foldr ((:) . f) []
-- move arguments around for easier reduction
map f = flip foldr [] ((:) . f)
-- reduce further with .
map = flip foldr [] . ((:) .)
-- rewrite flip using an infix section
map = (`foldr` []) . ((:) .)
-- What does this accomplish?
-- Not much. Don't bother.
-- But you may see code like this.
select
from Exercise 10 using foldr
without any explicit recursionselect (>5) [2,4,6,8,10] == [6,8,10]
runhaskell
to interpret themHello.hs
main = putStr "hello\n"
$ runhaskell Hello.hs
hello
Hello.hs
main = putStrLn "hello"
$ runhaskell Hello.hs
hello
Hello.hs
main = do
print "hello"
putStrLn (show "hello")
putStr (show "hello" ++ "\n")
$ runhaskell Hello.hs
"hello"
"hello"
"hello"
<-
binds the result of an IO action to a variablemain = do
putStrLn "Enter your name:"
name <- getLine
putStrLn ("You entered: " ++ name)
return
creates an IO action from a valuemain = do
putStrLn "Enter your name:"
name <- return "Bob"
putStrLn ("You entered: " ++ name)
main = do
putStrLn "Enter your name:"
name <- return "Bob"
putStrLn ("You entered: " ++ name)
main
nameLoop names = do
putStrLn "Who are you?"
name <- getLine
if name `elem` names
then do
putStrLn ("I already know " ++ name)
nameLoop names
else do
putStrLn ("Nice to meet you " ++ name)
nameLoop (name : names)
main = nameLoop []