Haskell is an advanced purely-functional programming language.
You can download Haskell Platform, Compiler and base libraries from Official Download.
For third party libraries, you can install using cabal:
$ cabal update
$ cabal install the-package
$ ghci
GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude>
Prelude> 1
1
Prelude> 1 + 2
3
Prelude> 1 + 2.0
3.0
Prelude> 1 + 2.0 * 3
7.0
Prelude> 1 * 2 + 3
5
Prelude> 1 * (2 + 3)
5
Prelude> 2 * (3 + 4)
14
Prelude> "hello"
"hello"
Prelude> "hello" + " world"
<interactive>:12:9:
No instance for (Num [Char]) arising from a use of ‘+’
In the expression: "hello" + " world"
In an equation for ‘it’: it = "hello" + " world"
Prelude> "hello" ++ " world"
"hello world"
Prelude> 'a'
'a'
Prelude> ['a', 'b']
"ab"
Prelude> (4 + 5) == 9
True
Prelude> (5 + 5) /= 10
False
Prelude> if (5 == 5) ten "true"
<interactive>:18:23:
parse error (possibly incorrect indentation or mismatched brackets)
Prelude> if (5 == 5) then "true" else "false"
"true"
Prelude> if 1 then "true" else "false"
<interactive>:2:4:
No instance for (Num Bool) arising from the literal ‘1’
In the expression: 1
In the expression: if 1 then "true" else "false"
In an equation for ‘it’: it = if 1 then "true" else "false"
Prelude> "one" + 1
<interactive>:7:7:
No instance for (Num [Char]) arising from a use of ‘+’
In the expression: "one" + 1
In an equation for ‘it’: it = "one" + 1
Prelude> :set +t
Prelude> 5
5
it :: Num a => a
Prelude> 5.0
5.0
it :: Fractional a => a
Prelude> "hello"
"hello"
it :: [Char]
Prelude> (5 == (2 + 3))
True
it :: Bool
Prelude> :t 5
5 :: Num a => a
Prelude> let x = 10
Prelude> x
10
Prelude> let double x = x * 2
Prelude> double 2
4
double.hs
module Main where
double x = x + x
Prelude> :load double.hs
[1 of 1] Compiling Main ( double.hs, interpreted )
Ok, modules loaded: Main.
*Main> double 5
10
double_with_type.hs
module Main where
double :: Integer -> Integer
double x = x + x
Prelude> :load double_with_type.hs
[1 of 1] Compiling Main ( double_with_type.hs, interpreted )
Ok, modules loaded: Main.
*Main> double 5
10
*Main> :t double
double :: Integer -> Integer
Prelude> let fact x = if x == 0 then 1 else fact (x - 1) * x
Prelude> fact 3
6
factorial.hs
module Main where
factorial :: Integer -> Integer
factorial 0 = 1
factorial x = x * factorial (x - 1)
fact_with_guard.hs
module Main where
factorial :: Integer -> Integer
factorial x
| x > 1 = x * factorial (x - 1)
| otherwise = 1
fib.hs
module Main where
fib :: Integer -> Integer
fib 0 = 1
fib 1 = 1
fib x = fib (x - 1) + fib (x - 2)
fib_tuple.hs
module Main where
fibTuple :: (Integer, Integer, Integer) -> (Integer, Integer, Integer)
fibTuple (x, y, 0) = (x, y, 0)
fibTuple (x, y, index) = fibTuple (y, x + y, index - 1)
fibResult :: (Integer, Integer, Integer) -> Integer
fibResult (x, y, z) = x
fib :: Integer -> Integer
fib x = fibResult (fibTuple (0, 1, x))
Prelude> :load fib_tuple.hs
[1 of 1] Compiling Main ( fib_tuple.hs, interpreted )
Ok, modules loaded: Main.
*Main> fibTuple(0, 1, 4)
(3,5,0)
*Main> fib 100
354224848179261915075
*Main> fib 1000
43466557686937456435688527675040625802564660517371780
40248172908953655541794905189040387984007925516929592
25930803226347752096896232398733224711616429964409065
33187938298969649928516003704476137795166849228875
*Main> let second = head . tail
*Main> second [1, 2]
2
*Main> second [3, 4, 5]
4
fib_pair.hs
module Main where
fibNextPair :: (Integer, Integer) -> (Integer, Integer)
fibNextPair (x, y) = (y, x + y)
fibNthPair :: Integer -> (Integer, Integer)
fibNthPair 1 = (1, 1)
fibNthPair n = fibNextPair (fibNthPair (n - 1))
fib :: Integer -> Integer
fib = fst . fibNthPair
*Main> :load fib_pair.hs
[1 of 1] Compiling Main ( fib_pair.hs, interpreted )
Ok, modules loaded: Main.
*Main> fibNthPair(8)
(21,34)
*Main> fibNthPair(9)
(34,55)
*Main> fibNthPair(10)
(55,89)
*Main> fib(8)
21
lists.hs
module Main where
size [] = 0
size (h:t) = 1 + size t
prod [] = 1
prod (h:t) = h * prod t
Prelude> let (h:t) = [1, 2, 3, 4]
Prelude> h
1
Prelude> t
[2,3,4]
Prelude> :load lists.hs
[1 of 1] Compiling Main ( lists.hs, interpreted )
Ok, modules loaded: Main.
*Main> size "Amazing."
8
*Main> zip "cat" "dog"
[('c','d'),('a','o'),('t','g')]
*Main> zip "cat" "tiger"
[('c','t'),('a','i'),('t','g')]
*Main> zip ["cat", "dog"] ["tiger", "lion"]
[("cat","tiger"),("dog","lion")]
*Main> let h:t = [1, 2, 3]
*Main> h
1
*Main> t
[2,3]
*Main> 1:[2, 3]
[1,2,3]
*Main> [1]:[2, 3]
<interactive>:14:1:
No instance for (Num [t0]) arising from a use of ‘it’
In a stmt of an interactive GHCi command: print it
*Main> [1]:[[2], [3, 4]]
[[1],[2],[3,4]]
*Main> [1]:[]
[[1]]
all_even.hs
module Main where
allEven :: [Integer] -> [Integer]
allEven [] = []
allEven (h:t) = if even h then h:allEven t else allEven t
Prelude> [1..2]
[1,2]
Prelude> [1..4]
[1,2,3,4]
Prelude> [10..4]
[]
Prelude> [10, 8 .. 4]
[10,8,6,4]
Prelude> [10, 9.5 .. 4]
[10.0,9.5,9.0,8.5,8.0,7.5,7.0,6.5,6.0,5.5,5.0,4.5,4.0]
Prelude> take 5 [1..]
[1,2,3,4,5]
Prelude> take 5 [0, 2 ..]
[0,2,4,6,8]
Prelude> [x * 2 | x <- [1, 2, 3]]
[2,4,6]
Prelude> [ (y, x) | (x, y) <- [(1, 2), (2, 3), (3, 4)]]
[(2,1),(3,2),(4,3)]
Prelude> [ (4 - x, y) | (x, y) <- [(1, 2), (2, 3), (3, 4)]]
[(3,2),(2,3),(1,4)]
Prelude> let colors = ["red", "green", "blue"]
Prelude> [(a, b) | a <- colors, b <- colors]
[("red","red"),("red","green"),("red","blue"),("green","red"),("green","green"),("green","blue"),("blue","red"),("blue","green"),("blue","blue")]
Prelude> [(a, b) | a <- colors, b <- colors, a /= b]
[("red","green"),("red","blue"),("green","red"),("green","blue"),("blue","red"),("blue","green")]
Prelude> [(a, b) | a <- colors, b <- colors, a < b]
[("green","red"),("blue","red"),("blue","green")]
Loading package base ... linking ... done.
Prelude> (\x -> x) "Logical."
"Logical."
Prelude> (\x -> x ++ " captian.") "Logical,"
"Logical, captian."
Prelude> map (\x -> x * x) [1, 2, 3]
[1,4,9]
map.hs
module Main where
squareAll list = map square list
where square x = x * x
Prelude> :load map.hs
[1 of 1] Compiling Main ( map.hs, interpreted )
Ok, modules loaded: Main.
*Main> squareAll [1, 2, 3]
[1,4,9]
*Main> map (+ 1) [1, 2, 3]
[2,3,4]
Prelude> odd 5
True
Prelude> filter odd [1, 2, 3, 4, 5]
[1,3,5]
Prelude> foldl (\x carryOver -> carryOver + x) 0 [1 .. 10]
55
Prelude> foldl1 (+) [1 .. 3]
6
Prelude> 1 + 2 + 3
6
Prelude>
Prelude> let prod x y = x * y
Prelude> prod 3 4
12
Prelude> :t prod
prod :: Num a => a -> a -> a
Prelude> let double = prod 2
Prelude> let triple = prod 3
Prelude> double 3
6
Prelude> triple 4
12
my_range.hs
module Main where
myRange start step = start:(myRange (start + step) step)
Prelude> :load my_range.hs
[1 of 1] Compiling Main ( my_range.hs, interpreted )
Ok, modules loaded: Main.
*Main> take 10 (myRange 10 1)
[10,11,12,13,14,15,16,17,18,19]
*Main> take 5 (myRange 0 5)
[0,5,10,15,20]
lazy_fib.hs
module Main where
lazyFib x y = x:(lazyFib y (x + y))
fib = lazyFib 1 1
fibNth x = head (drop (x - 1) (take (x) fib))
*Main> :load lazy_fib.hs
[1 of 1] Compiling Main ( lazy_fib.hs, interpreted )
Ok, modules loaded: Main.
*Main> take 5 (lazyFib 0 1)
[0,1,1,2,3]
*Main> take 5 (fib)
[1,1,2,3,5]
*Main> take 5 (drop 20 (lazyFib 0 1))
[6765,10946,17711,28657,46368]
*Main> fibNth 3
2
*Main> fibNth 6
8
*Main> take 5 (zipWith (+) fib (drop 1 fib))
[2,3,5,8,13]
*Main> take 5 (map (*2) [1 ..])
[2,4,6,8,10]
*Main> take 5 (map ((* 2) . (* 5)) fib)
[10,10,20,30,50]
Prelude> :set +t
Prelude> 'c'
'c'
it :: Char
Prelude> "hello"
"hello"
it :: [Char]
Prelude> ['a', 'b', 'c']
"abc"
it :: [Char]
Prelude> "hello" == ['h', 'e', 'l', 'l', 'o']
True
it :: Bool
Prelude> True
True
it :: Bool
Prelude> False
False
it :: Bool
cards.hs
module Main where
data Suit = Spades | Hearts
data Rank = Ten | Jack | Queen | King | Ace
cards-with-show.hs
module Main where
data Suit = Spades | Hearts deriving (Show)
data Rank = Ten | Jack | Queen | King | Ace deriving (Show)
type Card = (Rank, Suit)
type Hand = [Card]
value :: Rank -> Integer
value Ten = 1
value Jack = 2
value Queen = 3
value King = 4
value Ace = 5
cardValue :: Card -> Integer
cardValue (rank, suit) = value rank
Prelude> :load cards-with-show.hs
[1 of 1] Compiling Main ( cards-with-show.hs, interpreted )
Ok, modules loaded: Main.
*Main> cardValue (Ten, Hearts)
1
triplet.hs
module Main where
data Triplet a = Trio a a a deriving (Show)
*Main> :load triplet.hs
[1 of 1] Compiling Main ( triplet.hs, interpreted )
Ok, modules loaded: Main.
*Main> :t Trio 'a' 'b' 'c'
Trio 'a' 'b' 'c' :: Triplet Cha
tree.hs
module Main where
data Tree a = Children [Tree a] | Leaf a deriving (Show)
depth (Leaf _) = 1
depth (Children c) = 1 + maximum (map depth c)
Prelude> :load tree.hs
[1 of 1] Compiling Main ( tree.hs, interpreted )
Ok, modules loaded: Main.
*Main> let leaf = Leaf 1
*Main> leaf
Leaf 1
*Main> let (Leaf value) = leaf
*Main> value
1
*Main> Children[Leaf 1, Leaf 2]
Children [Leaf 1,Leaf 2]
*Main> let tree = Children[Leaf 1, Children [Leaf 2, Leaf 3]]
*Main> tree
Children [Leaf 1,Children [Leaf 2,Leaf 3]]
*Main> let (Children ch) = tree
*Main> ch
[Leaf 1,Children [Leaf 2,Leaf 3]]
*Main> let (fst:tail) = ch
*Main> fst
Leaf 1
drunken-pirate.hs
module Main where
stagger :: (Num t) => t -> t
stagger d = d + 2
crawl d = d + 1
treasureMap d =
crawl (
stagger (
stagger d))
letTreasureMap (v, d) = let d1 = stagger d
d2 = stagger d1
d3 = crawl d2
in d3
drunken-monad.hs
module Main where
data Position t = Position t deriving (Show)
stagger (Position d) = Position (d + 2)
crawl (Position d) = Position (d + 1)
rtn x = x
x >>== f = f x
treasureMap pos = pos >>==
stagger >>==
stagger >>==
crawl >>==
rtn
Prelude> :load drunken-monad.hs
[1 of 1] Compiling Main ( drunken-monad.hs, interpreted )
Ok, modules loaded: Main.
*Main> treasureMap (Position 0)
Position 5
*Main>
io.hs
module Main where
tryIo = do putStr "Enter your name: " ;
line <- getLine ;
let { backwards = reverse line } ;
return ("Hello. Your name backwards is " ++ backwards)
*Main> :load io.hs
[1 of 1] Compiling Main ( io.hs, interpreted )
Ok, modules loaded: Main.
*Main> tryIo
Enter your name: Jeoygin
"Hello. Your name backwards is nigyoeJ"
instance Monad [] where
m >>= f = concatMap f m
return x = [x]
*Main> let cartesian (xs, ys) = do x <- xs; y <- ys; return (x, y)
*Main> cartesian ([1..2], [3..4])
[(1,3),(1,4),(2,3),(2,4)]
password.hs
module Main where
crack = do x <- ['a'..'c'] ; y <- ['a'..'c'] ; z <- ['a'..'c'] ;
let { password = [x, y, z] } ;
if attempt password
then return (password, True)
else return (password, False)
attempt pw = if pw == "cab" then True else False
*Main> :load password.hs
[1 of 1] Compiling Main ( password.hs, interpreted )
Ok, modules loaded: Main.
*Main> crack
[("aaa",False),("aab",False),("aac",False),("aba",False),("abb",False),("abc",False),("aca",False),("acb",False),("acc",False),("baa",False),("bab",False),("bac",False),("bba",False),("bbb",False),("bbc",False),("bca",False),("bcb",False),("bcc",False),("caa",False),("cab",True),("cac",False),("cba",False),("cbb",False),("cbc",False),("cca",False),("ccb",False),("ccc",False)]
Prelude> Just "some string"
Just "some string"
Prelude> Just Nothing
Just Nothing
case (html doc) of
Nothing -> Nothing
Just x -> case body x of
Nothing -> Nothing
Just y -> paragraph 2 y
data Maybe a = Nothing | Just a
instance Monad Maybe where
return = Just
Nothing >>= f = Nothing
(Just x) >>= f = f x
Just someWebPage >>= html >>= body >>= paragraph >>= return