Haskell 2016Edit
Notes made while (re-)learning Haskell in 2016.
Resources
Books
- Learn You a Haskell for Great Good! (readable online for free)
 - Haskell Programming from first principles (still in early access)
 - Real World Haskell (O’Reilly, readable online for free)
 - Maybe Haskell (non-free)
 
Practice problems
Tutorials
- Write Yourself a Scheme in 48 Hours
 
- Hitchhikers guide to Haskell
 
- The Monad Challenges
 
- Bryan O’Sullivan’s CS240H lecture notes (Winter)
 
- Bryan O’Sullivan’s CS240H lecture notes (Spring)
 
Reference
Meta: How to learn Haskell
Other links
Notes
Installation
$ brew install ghc cabal-install
Command line
$ ghci              # Start a REPL.
$ runhaskell src.hs # Run code without separate compilation step.
$ runghc src.hs     # Equivalent to runhaskell.
$ ghc --make src.hs # Compile.
$ ghc-pkg list      # See installed packages.
ghci
:?: show help 
:cd [directory]: change working directory 
:info [name]: show information about name (a type, a typeclass, a binding etc) 
:load [path]: load module from path (relative to working directory, or absolute, with or without .hs extension) 
:m +[module]: load module 
:set +t: show type information for each evaluated expression 
:set prompt "ghci> ": override default prompt 
:show bindings: show all bound variables 
:type [expression] (:t [expression]): show the type for the given expression 
:unset +t: don’t show type information 
it: variable bound to the value of the last evaluated expression 
Prelude functions
&& :: Bool -> Bool -> Bool … short-circuiting boolean operator. 
++ :: [a] -> [a] -> [a] 
break :: (a -> Bool) -> [a] -> ([a], [a]) … breaks a list into two (consumes input while predicate fails). 
span :: (a -> Bool) -> [a] -> ([a], [a]) … breaks a list into two (consumes input while predicate succeeds). 
ceiling :: (Integral b, RealFrac a) => a -> b 
splitAt :: Int -> [a] -> ([a], [a]) 
takeWhile :: (a -> Bool) -> [a] -> [a] 
dropWhile :: (a -> Bool) -> [a] -> [a] 
compare :: Ord a => a -> a -> Ordering 
concat :: Foldable t => t [a] -> [a] 
drop :: Int -> [a] -> [a] 
elem :: (Eq a, Foldable t) => a -> t a -> Bool 
zip :: [a] -> [b] -> [(a, b)]) … also has variants for up to 7 lists (zip7). 
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]) … also has variants for up to 7 lists (zipWith7). 
notElem :: (Eq a, Foldable t) => a -> t a -> Bool 
error :: [Char] -> a 
floor :: (Integral b, RealFrac a) => a -> b 
fromIntegral :: (Integral a, Num b) => a -> b 
fst :: (a, b) -> a 
head :: [a] -> a … first element of list (raises an exception if applied to an empty list) 
init … all but last element of a list (raises exception if applied to an empty list) 
last … last element of a list (raises exception if applied to an empty list) 
length :: Foldable t => t a -> Int 
lines :: String -> [String] 
mod :: Integral a => a -> a -> a … modulo (remainder after division) 
filter :: (a -> Bool) -> [a] -> [a] 
not :: Bool -> Bool 
null :: Foldable t => t a -> Bool … indicates whether a list is empty 
odd :: Integral a => a -> Bool 
even :: Integral a => a -> Bool 
map :: (a -> b) -> [a] -> [b] … but consider using fmap instead. 
negate :: Num a => a -> a 
pred :: Enum a => a -> a 
print :: Show a => a -> IO () 
read :: Read a => String -> a 
show :: Show a => a -> String 
readFile :: FilePath -> IO String 
reverse :: [a] -> [a] 
round :: (Integral b, RealFrac a) => a -> b 
snd :: (a, b) -> b 
sqrt :: Floating a => a -> a 
succ :: Enum a => a -> a 
tail :: [a] -> [a] … non-head part of list (raises an exception if applied to an empty list) 
take :: Int -> [a] -> [a] 
truncate :: (Integral b, RealFrac a) => a -> b 
unlines :: [String] -> String 
words :: String -> [String] 
unwords :: [String] -> String 
|| :: Bool -> Bool -> Bool … short-circuiting boolean operator 
and :: Foldable t => t Bool -> Bool 
or :: Foldable t => t Bool -> Bool 
all :: Foldable t => (a -> Bool) -> t a -> Bool 
any :: Foldable t => (a -> Bool) -> t a -> Bool 
seq :: a -> b -> b … force non-lazy evaluation of first argument, then return second argument 
intercalate :: [a] -> [[a]] -> [a] 
Data.Bits
.|. :: Bits a => a -> a -> a 
.&. :: Bits a => a -> a -> a 
shiftL :: Bits a => a -> Int -> a 
shiftR :: Bits a => a -> Int -> a 
Data.Char
digitToInt :: Char -> Int 
ord :: Char -> Int 
toUpper :: Char -> Char 
Data.List
isInfixOf :: Eq a => [a] -> [a] -> Bool 
isPrefixOf :: Eq a => [a] -> [a] -> Bool 
isSuffixOf :: Eq a => [a] -> [a] -> Bool 
tails :: [a] -> [[a]] … returns all tails of a list 
Data.ratio
% :: Integral a => a -> a -> Ratio a 
Debug.Trace
trace :: String -> a -> a 
traceM :: String -> m () (for use in do notation) 
Numeric
showHex :: (Integral a, Show a) => a -> ShowS 
Syntax
--: begin a single-line comment 
{- ... -}: in-line comment 
if/then/else: conditional expression 
$: function application (low precedence) 
.: function composition ((f . g) x is same as f (g x)). 
let + in: create bound variables with the scope of an expression 
where: like let, but at top level of equation; not an expression 
case (something) of (pattern) -> expression: pattern matching within expressions 
|: guard (additionally restricts a pattern match) 
`fn` (backticks): apply fn in infix position 
foo@(x:xs) ("as-pattern"): refer to entirety of pattern match contents 
::: disambiguate a type (eg. read "5" :: Double) 
Importing modules
import Data.Set -- import everything from Data.Set (unqualified dump into top-level scope)
import Data.Set (member, union) -- import only named bindings
import qualified Data.Set -- import everything, but bound as Data.Set.{name}
import qualified Data.Set as Set -- import using an alias Set.{name}
import qualified Data.Set as Set (member, union) -- partial, aliased, qualified import
Defining modules
-- Simple: Foo.hs
module Foo (bar, baz) where
  bar = 1
  baz = id
-- Nested: Bar/Baz.hs
module Bar.Baz (
  , Thing -- export (abstract/opaque) type but not constructor(s)
  , Other(..) -- exports type and constructors (for pattern matching etc)
  , x
  ) where
  data Thing = Thing Int
  data Other = Other String
  x = 2
Types
Double: double-precision floating point. 
Float: single-precision floating point. 
Int: fixed precision signed integer (bounds are architecture-dependent and given by maxBound :: Int and minBound :: Int). 
Word: fixed precision unsigned integer (bounds: minBound :: Word — ie. 0 — and maxBound :: Word). 
Integer: arbitrary precision integer. 
Defining new types
-- "Thing" type constructor (for pattern matching)
-- "Thing" value constructor (for creating values of the type)
data Thing = Thing Int String [String]
             deriving (Eq, Show)
-- Record syntax (note: no trailing comma allowed)
data Thing = Thing {
          customerID :: CustomerID,
          customerName :: String,
          customerAddress :: [String]
        } deriving (Eq, Show)
-- Create values using either named fields:
myThing = Thing { customerID = 1234, customerName = "Jane", customerAddress = ["PO Box 1"] }
-- Or anonymous, ordered fields:
myThing = Thing 1234 "John" ["1 Infinite Loop"]
-- Algebraic types with multiple value constructors
data PaymentRecord = CreditCard | CashAccount
data Color = Red | Green | Blue deriving (Eq, Show)
-- Create a synonym for an existing type
type RecordLocator = String
-- Same, but for a tuple
type ContactDetails = (Name, PhoneNumber, Address)
-- Wrap a type to present it as something else (eg. List as ZipList).
-- Can only have one value constructor, and constructor can only have one field.
newtype ZipList a = ZipList { getZipList :: [a] }
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
Type classes
-- Definition
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x == y = not (x /= y) -- note the circularity here
  x /= y = not (x == y) -- meaning that you only have to implement one
-- Making a type an instance of a type class
data MyStatus = Started | Stopped
instance Eq MyStatus where
  Started == Started = True
  Stopped == Stopped = True
  _ == _ = False
-- Types can be instances of many type classes at once
instance Show MyStatus where
  show Started = "Started"
  show Stopped = "Stopped"
-- Defining a subclass of another typeclass
-- (in order to be an instance of `Num`, you must be an instance of `Eq`)
class (Eq a) => Num where
  ...
-- Parameterized types as instances of type classes
-- (works for `Mabye Int`, `Maybe Char`, `Maybe Something` etc,
-- as long as `Something` is an instance of the `Eq` typeclass)
instance (Eq m) => Eq (Maybe m) where
  Just x == Just y = x == y
  Nothing == Nothing = true
  _ == _ = False
-- Show instances of a type class
:info Maybe
Pattern matching
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Pragmas
- Write Yourself a Scheme in 48 Hours
 - Hitchhikers guide to Haskell
 - The Monad Challenges
 - Bryan O’Sullivan’s CS240H lecture notes (Winter)
 - Bryan O’Sullivan’s CS240H lecture notes (Spring)
 
Reference
Meta: How to learn Haskell
Other links
Notes
Installation
$ brew install ghc cabal-install
Command line
$ ghci              # Start a REPL.
$ runhaskell src.hs # Run code without separate compilation step.
$ runghc src.hs     # Equivalent to runhaskell.
$ ghc --make src.hs # Compile.
$ ghc-pkg list      # See installed packages.
ghci
:?: show help 
:cd [directory]: change working directory 
:info [name]: show information about name (a type, a typeclass, a binding etc) 
:load [path]: load module from path (relative to working directory, or absolute, with or without .hs extension) 
:m +[module]: load module 
:set +t: show type information for each evaluated expression 
:set prompt "ghci> ": override default prompt 
:show bindings: show all bound variables 
:type [expression] (:t [expression]): show the type for the given expression 
:unset +t: don’t show type information 
it: variable bound to the value of the last evaluated expression 
Prelude functions
&& :: Bool -> Bool -> Bool … short-circuiting boolean operator. 
++ :: [a] -> [a] -> [a] 
break :: (a -> Bool) -> [a] -> ([a], [a]) … breaks a list into two (consumes input while predicate fails). 
span :: (a -> Bool) -> [a] -> ([a], [a]) … breaks a list into two (consumes input while predicate succeeds). 
ceiling :: (Integral b, RealFrac a) => a -> b 
splitAt :: Int -> [a] -> ([a], [a]) 
takeWhile :: (a -> Bool) -> [a] -> [a] 
dropWhile :: (a -> Bool) -> [a] -> [a] 
compare :: Ord a => a -> a -> Ordering 
concat :: Foldable t => t [a] -> [a] 
drop :: Int -> [a] -> [a] 
elem :: (Eq a, Foldable t) => a -> t a -> Bool 
zip :: [a] -> [b] -> [(a, b)]) … also has variants for up to 7 lists (zip7). 
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]) … also has variants for up to 7 lists (zipWith7). 
notElem :: (Eq a, Foldable t) => a -> t a -> Bool 
error :: [Char] -> a 
floor :: (Integral b, RealFrac a) => a -> b 
fromIntegral :: (Integral a, Num b) => a -> b 
fst :: (a, b) -> a 
head :: [a] -> a … first element of list (raises an exception if applied to an empty list) 
init … all but last element of a list (raises exception if applied to an empty list) 
last … last element of a list (raises exception if applied to an empty list) 
length :: Foldable t => t a -> Int 
lines :: String -> [String] 
mod :: Integral a => a -> a -> a … modulo (remainder after division) 
filter :: (a -> Bool) -> [a] -> [a] 
not :: Bool -> Bool 
null :: Foldable t => t a -> Bool … indicates whether a list is empty 
odd :: Integral a => a -> Bool 
even :: Integral a => a -> Bool 
map :: (a -> b) -> [a] -> [b] … but consider using fmap instead. 
negate :: Num a => a -> a 
pred :: Enum a => a -> a 
print :: Show a => a -> IO () 
read :: Read a => String -> a 
show :: Show a => a -> String 
readFile :: FilePath -> IO String 
reverse :: [a] -> [a] 
round :: (Integral b, RealFrac a) => a -> b 
snd :: (a, b) -> b 
sqrt :: Floating a => a -> a 
succ :: Enum a => a -> a 
tail :: [a] -> [a] … non-head part of list (raises an exception if applied to an empty list) 
take :: Int -> [a] -> [a] 
truncate :: (Integral b, RealFrac a) => a -> b 
unlines :: [String] -> String 
words :: String -> [String] 
unwords :: [String] -> String 
|| :: Bool -> Bool -> Bool … short-circuiting boolean operator 
and :: Foldable t => t Bool -> Bool 
or :: Foldable t => t Bool -> Bool 
all :: Foldable t => (a -> Bool) -> t a -> Bool 
any :: Foldable t => (a -> Bool) -> t a -> Bool 
seq :: a -> b -> b … force non-lazy evaluation of first argument, then return second argument 
intercalate :: [a] -> [[a]] -> [a] 
Data.Bits
.|. :: Bits a => a -> a -> a 
.&. :: Bits a => a -> a -> a 
shiftL :: Bits a => a -> Int -> a 
shiftR :: Bits a => a -> Int -> a 
Data.Char
digitToInt :: Char -> Int 
ord :: Char -> Int 
toUpper :: Char -> Char 
Data.List
isInfixOf :: Eq a => [a] -> [a] -> Bool 
isPrefixOf :: Eq a => [a] -> [a] -> Bool 
isSuffixOf :: Eq a => [a] -> [a] -> Bool 
tails :: [a] -> [[a]] … returns all tails of a list 
Data.ratio
% :: Integral a => a -> a -> Ratio a 
Debug.Trace
trace :: String -> a -> a 
traceM :: String -> m () (for use in do notation) 
Numeric
showHex :: (Integral a, Show a) => a -> ShowS 
Syntax
--: begin a single-line comment 
{- ... -}: in-line comment 
if/then/else: conditional expression 
$: function application (low precedence) 
.: function composition ((f . g) x is same as f (g x)). 
let + in: create bound variables with the scope of an expression 
where: like let, but at top level of equation; not an expression 
case (something) of (pattern) -> expression: pattern matching within expressions 
|: guard (additionally restricts a pattern match) 
`fn` (backticks): apply fn in infix position 
foo@(x:xs) ("as-pattern"): refer to entirety of pattern match contents 
::: disambiguate a type (eg. read "5" :: Double) 
Importing modules
import Data.Set -- import everything from Data.Set (unqualified dump into top-level scope)
import Data.Set (member, union) -- import only named bindings
import qualified Data.Set -- import everything, but bound as Data.Set.{name}
import qualified Data.Set as Set -- import using an alias Set.{name}
import qualified Data.Set as Set (member, union) -- partial, aliased, qualified import
Defining modules
-- Simple: Foo.hs
module Foo (bar, baz) where
  bar = 1
  baz = id
-- Nested: Bar/Baz.hs
module Bar.Baz (
  , Thing -- export (abstract/opaque) type but not constructor(s)
  , Other(..) -- exports type and constructors (for pattern matching etc)
  , x
  ) where
  data Thing = Thing Int
  data Other = Other String
  x = 2
Types
Double: double-precision floating point. 
Float: single-precision floating point. 
Int: fixed precision signed integer (bounds are architecture-dependent and given by maxBound :: Int and minBound :: Int). 
Word: fixed precision unsigned integer (bounds: minBound :: Word — ie. 0 — and maxBound :: Word). 
Integer: arbitrary precision integer. 
Defining new types
-- "Thing" type constructor (for pattern matching)
-- "Thing" value constructor (for creating values of the type)
data Thing = Thing Int String [String]
             deriving (Eq, Show)
-- Record syntax (note: no trailing comma allowed)
data Thing = Thing {
          customerID :: CustomerID,
          customerName :: String,
          customerAddress :: [String]
        } deriving (Eq, Show)
-- Create values using either named fields:
myThing = Thing { customerID = 1234, customerName = "Jane", customerAddress = ["PO Box 1"] }
-- Or anonymous, ordered fields:
myThing = Thing 1234 "John" ["1 Infinite Loop"]
-- Algebraic types with multiple value constructors
data PaymentRecord = CreditCard | CashAccount
data Color = Red | Green | Blue deriving (Eq, Show)
-- Create a synonym for an existing type
type RecordLocator = String
-- Same, but for a tuple
type ContactDetails = (Name, PhoneNumber, Address)
-- Wrap a type to present it as something else (eg. List as ZipList).
-- Can only have one value constructor, and constructor can only have one field.
newtype ZipList a = ZipList { getZipList :: [a] }
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
Type classes
-- Definition
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x == y = not (x /= y) -- note the circularity here
  x /= y = not (x == y) -- meaning that you only have to implement one
-- Making a type an instance of a type class
data MyStatus = Started | Stopped
instance Eq MyStatus where
  Started == Started = True
  Stopped == Stopped = True
  _ == _ = False
-- Types can be instances of many type classes at once
instance Show MyStatus where
  show Started = "Started"
  show Stopped = "Stopped"
-- Defining a subclass of another typeclass
-- (in order to be an instance of `Num`, you must be an instance of `Eq`)
class (Eq a) => Num where
  ...
-- Parameterized types as instances of type classes
-- (works for `Mabye Int`, `Maybe Char`, `Maybe Something` etc,
-- as long as `Something` is an instance of the `Eq` typeclass)
instance (Eq m) => Eq (Maybe m) where
  Just x == Just y = x == y
  Nothing == Nothing = true
  _ == _ = False
-- Show instances of a type class
:info Maybe
Pattern matching
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Pragmas
Other links
Notes
Installation
$ brew install ghc cabal-install
Command line
$ ghci              # Start a REPL.
$ runhaskell src.hs # Run code without separate compilation step.
$ runghc src.hs     # Equivalent to runhaskell.
$ ghc --make src.hs # Compile.
$ ghc-pkg list      # See installed packages.
ghci
:?: show help 
:cd [directory]: change working directory 
:info [name]: show information about name (a type, a typeclass, a binding etc) 
:load [path]: load module from path (relative to working directory, or absolute, with or without .hs extension) 
:m +[module]: load module 
:set +t: show type information for each evaluated expression 
:set prompt "ghci> ": override default prompt 
:show bindings: show all bound variables 
:type [expression] (:t [expression]): show the type for the given expression 
:unset +t: don’t show type information 
it: variable bound to the value of the last evaluated expression 
Prelude functions
&& :: Bool -> Bool -> Bool … short-circuiting boolean operator. 
++ :: [a] -> [a] -> [a] 
break :: (a -> Bool) -> [a] -> ([a], [a]) … breaks a list into two (consumes input while predicate fails). 
span :: (a -> Bool) -> [a] -> ([a], [a]) … breaks a list into two (consumes input while predicate succeeds). 
ceiling :: (Integral b, RealFrac a) => a -> b 
splitAt :: Int -> [a] -> ([a], [a]) 
takeWhile :: (a -> Bool) -> [a] -> [a] 
dropWhile :: (a -> Bool) -> [a] -> [a] 
compare :: Ord a => a -> a -> Ordering 
concat :: Foldable t => t [a] -> [a] 
drop :: Int -> [a] -> [a] 
elem :: (Eq a, Foldable t) => a -> t a -> Bool 
zip :: [a] -> [b] -> [(a, b)]) … also has variants for up to 7 lists (zip7). 
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]) … also has variants for up to 7 lists (zipWith7). 
notElem :: (Eq a, Foldable t) => a -> t a -> Bool 
error :: [Char] -> a 
floor :: (Integral b, RealFrac a) => a -> b 
fromIntegral :: (Integral a, Num b) => a -> b 
fst :: (a, b) -> a 
head :: [a] -> a … first element of list (raises an exception if applied to an empty list) 
init … all but last element of a list (raises exception if applied to an empty list) 
last … last element of a list (raises exception if applied to an empty list) 
length :: Foldable t => t a -> Int 
lines :: String -> [String] 
mod :: Integral a => a -> a -> a … modulo (remainder after division) 
filter :: (a -> Bool) -> [a] -> [a] 
not :: Bool -> Bool 
null :: Foldable t => t a -> Bool … indicates whether a list is empty 
odd :: Integral a => a -> Bool 
even :: Integral a => a -> Bool 
map :: (a -> b) -> [a] -> [b] … but consider using fmap instead. 
negate :: Num a => a -> a 
pred :: Enum a => a -> a 
print :: Show a => a -> IO () 
read :: Read a => String -> a 
show :: Show a => a -> String 
readFile :: FilePath -> IO String 
reverse :: [a] -> [a] 
round :: (Integral b, RealFrac a) => a -> b 
snd :: (a, b) -> b 
sqrt :: Floating a => a -> a 
succ :: Enum a => a -> a 
tail :: [a] -> [a] … non-head part of list (raises an exception if applied to an empty list) 
take :: Int -> [a] -> [a] 
truncate :: (Integral b, RealFrac a) => a -> b 
unlines :: [String] -> String 
words :: String -> [String] 
unwords :: [String] -> String 
|| :: Bool -> Bool -> Bool … short-circuiting boolean operator 
and :: Foldable t => t Bool -> Bool 
or :: Foldable t => t Bool -> Bool 
all :: Foldable t => (a -> Bool) -> t a -> Bool 
any :: Foldable t => (a -> Bool) -> t a -> Bool 
seq :: a -> b -> b … force non-lazy evaluation of first argument, then return second argument 
intercalate :: [a] -> [[a]] -> [a] 
Data.Bits
.|. :: Bits a => a -> a -> a 
.&. :: Bits a => a -> a -> a 
shiftL :: Bits a => a -> Int -> a 
shiftR :: Bits a => a -> Int -> a 
Data.Char
digitToInt :: Char -> Int 
ord :: Char -> Int 
toUpper :: Char -> Char 
Data.List
isInfixOf :: Eq a => [a] -> [a] -> Bool 
isPrefixOf :: Eq a => [a] -> [a] -> Bool 
isSuffixOf :: Eq a => [a] -> [a] -> Bool 
tails :: [a] -> [[a]] … returns all tails of a list 
Data.ratio
% :: Integral a => a -> a -> Ratio a 
Debug.Trace
trace :: String -> a -> a 
traceM :: String -> m () (for use in do notation) 
Numeric
showHex :: (Integral a, Show a) => a -> ShowS 
Syntax
--: begin a single-line comment 
{- ... -}: in-line comment 
if/then/else: conditional expression 
$: function application (low precedence) 
.: function composition ((f . g) x is same as f (g x)). 
let + in: create bound variables with the scope of an expression 
where: like let, but at top level of equation; not an expression 
case (something) of (pattern) -> expression: pattern matching within expressions 
|: guard (additionally restricts a pattern match) 
`fn` (backticks): apply fn in infix position 
foo@(x:xs) ("as-pattern"): refer to entirety of pattern match contents 
::: disambiguate a type (eg. read "5" :: Double) 
Importing modules
import Data.Set -- import everything from Data.Set (unqualified dump into top-level scope)
import Data.Set (member, union) -- import only named bindings
import qualified Data.Set -- import everything, but bound as Data.Set.{name}
import qualified Data.Set as Set -- import using an alias Set.{name}
import qualified Data.Set as Set (member, union) -- partial, aliased, qualified import
Defining modules
-- Simple: Foo.hs
module Foo (bar, baz) where
  bar = 1
  baz = id
-- Nested: Bar/Baz.hs
module Bar.Baz (
  , Thing -- export (abstract/opaque) type but not constructor(s)
  , Other(..) -- exports type and constructors (for pattern matching etc)
  , x
  ) where
  data Thing = Thing Int
  data Other = Other String
  x = 2
Types
Double: double-precision floating point. 
Float: single-precision floating point. 
Int: fixed precision signed integer (bounds are architecture-dependent and given by maxBound :: Int and minBound :: Int). 
Word: fixed precision unsigned integer (bounds: minBound :: Word — ie. 0 — and maxBound :: Word). 
Integer: arbitrary precision integer. 
Defining new types
-- "Thing" type constructor (for pattern matching)
-- "Thing" value constructor (for creating values of the type)
data Thing = Thing Int String [String]
             deriving (Eq, Show)
-- Record syntax (note: no trailing comma allowed)
data Thing = Thing {
          customerID :: CustomerID,
          customerName :: String,
          customerAddress :: [String]
        } deriving (Eq, Show)
-- Create values using either named fields:
myThing = Thing { customerID = 1234, customerName = "Jane", customerAddress = ["PO Box 1"] }
-- Or anonymous, ordered fields:
myThing = Thing 1234 "John" ["1 Infinite Loop"]
-- Algebraic types with multiple value constructors
data PaymentRecord = CreditCard | CashAccount
data Color = Red | Green | Blue deriving (Eq, Show)
-- Create a synonym for an existing type
type RecordLocator = String
-- Same, but for a tuple
type ContactDetails = (Name, PhoneNumber, Address)
-- Wrap a type to present it as something else (eg. List as ZipList).
-- Can only have one value constructor, and constructor can only have one field.
newtype ZipList a = ZipList { getZipList :: [a] }
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
Type classes
-- Definition
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x == y = not (x /= y) -- note the circularity here
  x /= y = not (x == y) -- meaning that you only have to implement one
-- Making a type an instance of a type class
data MyStatus = Started | Stopped
instance Eq MyStatus where
  Started == Started = True
  Stopped == Stopped = True
  _ == _ = False
-- Types can be instances of many type classes at once
instance Show MyStatus where
  show Started = "Started"
  show Stopped = "Stopped"
-- Defining a subclass of another typeclass
-- (in order to be an instance of `Num`, you must be an instance of `Eq`)
class (Eq a) => Num where
  ...
-- Parameterized types as instances of type classes
-- (works for `Mabye Int`, `Maybe Char`, `Maybe Something` etc,
-- as long as `Something` is an instance of the `Eq` typeclass)
instance (Eq m) => Eq (Maybe m) where
  Just x == Just y = x == y
  Nothing == Nothing = true
  _ == _ = False
-- Show instances of a type class
:info Maybe
Pattern matching
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Pragmas
Installation
$ brew install ghc cabal-install
$ ghci              # Start a REPL.
$ runhaskell src.hs # Run code without separate compilation step.
$ runghc src.hs     # Equivalent to runhaskell.
$ ghc --make src.hs # Compile.
$ ghc-pkg list      # See installed packages.
ghci
:?: show help 
:cd [directory]: change working directory 
:info [name]: show information about name (a type, a typeclass, a binding etc) 
:load [path]: load module from path (relative to working directory, or absolute, with or without .hs extension) 
:m +[module]: load module 
:set +t: show type information for each evaluated expression 
:set prompt "ghci> ": override default prompt 
:show bindings: show all bound variables 
:type [expression] (:t [expression]): show the type for the given expression 
:unset +t: don’t show type information 
it: variable bound to the value of the last evaluated expression 
Prelude functions
:?: show help:cd [directory]: change working directory:info [name]: show information about name (a type, a typeclass, a binding etc):load [path]: load module from path (relative to working directory, or absolute, with or without .hs extension):m +[module]: load module:set +t: show type information for each evaluated expression:set prompt "ghci> ": override default prompt:show bindings: show all bound variables:type [expression] (:t [expression]): show the type for the given expression:unset +t: don’t show type informationit: variable bound to the value of the last evaluated expression&&::Bool -> Bool -> Bool… short-circuiting boolean operator.++::[a] -> [a] -> [a]break::(a -> Bool) -> [a] -> ([a], [a])… breaks a list into two (consumes input while predicate fails).span::(a -> Bool) -> [a] -> ([a], [a])… breaks a list into two (consumes input while predicate succeeds).ceiling::(Integral b, RealFrac a) => a -> bsplitAt::Int -> [a] -> ([a], [a])takeWhile::(a -> Bool) -> [a] -> [a]dropWhile::(a -> Bool) -> [a] -> [a]compare::Ord a => a -> a -> Orderingconcat::Foldable t => t [a] -> [a]drop::Int -> [a] -> [a]elem::(Eq a, Foldable t) => a -> t a -> Boolzip::[a] -> [b] -> [(a, b)]) … also has variants for up to 7 lists (zip7).zipWith::(a -> b -> c) -> [a] -> [b] -> [c]) … also has variants for up to 7 lists (zipWith7).notElem::(Eq a, Foldable t) => a -> t a -> Boolerror::[Char] -> afloor::(Integral b, RealFrac a) => a -> bfromIntegral::(Integral a, Num b) => a -> bfst::(a, b) -> ahead::[a] -> a… first element of list (raises an exception if applied to an empty list)init… all but last element of a list (raises exception if applied to an empty list)last… last element of a list (raises exception if applied to an empty list)length::Foldable t => t a -> Intlines::String -> [String]mod::Integral a => a -> a -> a… modulo (remainder after division)filter::(a -> Bool) -> [a] -> [a]not::Bool -> Boolnull::Foldable t => t a -> Bool… indicates whether a list is emptyodd::Integral a => a -> Booleven::Integral a => a -> Boolmap::(a -> b) -> [a] -> [b]… but consider usingfmapinstead.negate::Num a => a -> apred::Enum a => a -> aprint::Show a => a -> IO ()read::Read a => String -> ashow::Show a => a -> StringreadFile::FilePath -> IO Stringreverse::[a] -> [a]round::(Integral b, RealFrac a) => a -> bsnd::(a, b) -> bsqrt::Floating a => a -> asucc::Enum a => a -> atail::[a] -> [a]… non-head part of list (raises an exception if applied to an empty list)take::Int -> [a] -> [a]truncate::(Integral b, RealFrac a) => a -> bunlines::[String] -> Stringwords::String -> [String]unwords::[String] -> String||::Bool -> Bool -> Bool… short-circuiting boolean operatorand::Foldable t => t Bool -> Boolor::Foldable t => t Bool -> Boolall::Foldable t => (a -> Bool) -> t a -> Boolany::Foldable t => (a -> Bool) -> t a -> Boolseq::a -> b -> b… force non-lazy evaluation of first argument, then return second argumentintercalate::[a] -> [[a]] -> [a]
Data.Bits
.|. :: Bits a => a -> a -> a 
.&. :: Bits a => a -> a -> a 
shiftL :: Bits a => a -> Int -> a 
shiftR :: Bits a => a -> Int -> a 
Data.Char
digitToInt :: Char -> Int 
ord :: Char -> Int 
toUpper :: Char -> Char 
Data.List
isInfixOf :: Eq a => [a] -> [a] -> Bool 
isPrefixOf :: Eq a => [a] -> [a] -> Bool 
isSuffixOf :: Eq a => [a] -> [a] -> Bool 
tails :: [a] -> [[a]] … returns all tails of a list 
Data.ratio
% :: Integral a => a -> a -> Ratio a 
Debug.Trace
trace :: String -> a -> a 
traceM :: String -> m () (for use in do notation) 
Numeric
showHex :: (Integral a, Show a) => a -> ShowS 
Syntax
--: begin a single-line comment 
{- ... -}: in-line comment 
if/then/else: conditional expression 
$: function application (low precedence) 
.: function composition ((f . g) x is same as f (g x)). 
let + in: create bound variables with the scope of an expression 
where: like let, but at top level of equation; not an expression 
case (something) of (pattern) -> expression: pattern matching within expressions 
|: guard (additionally restricts a pattern match) 
`fn` (backticks): apply fn in infix position 
foo@(x:xs) ("as-pattern"): refer to entirety of pattern match contents 
::: disambiguate a type (eg. read "5" :: Double) 
Importing modules
import Data.Set -- import everything from Data.Set (unqualified dump into top-level scope)
import Data.Set (member, union) -- import only named bindings
import qualified Data.Set -- import everything, but bound as Data.Set.{name}
import qualified Data.Set as Set -- import using an alias Set.{name}
import qualified Data.Set as Set (member, union) -- partial, aliased, qualified import
Defining modules
-- Simple: Foo.hs
module Foo (bar, baz) where
  bar = 1
  baz = id
-- Nested: Bar/Baz.hs
module Bar.Baz (
  , Thing -- export (abstract/opaque) type but not constructor(s)
  , Other(..) -- exports type and constructors (for pattern matching etc)
  , x
  ) where
  data Thing = Thing Int
  data Other = Other String
  x = 2
Types
Double: double-precision floating point. 
Float: single-precision floating point. 
Int: fixed precision signed integer (bounds are architecture-dependent and given by maxBound :: Int and minBound :: Int). 
Word: fixed precision unsigned integer (bounds: minBound :: Word — ie. 0 — and maxBound :: Word). 
Integer: arbitrary precision integer. 
Defining new types
-- "Thing" type constructor (for pattern matching)
-- "Thing" value constructor (for creating values of the type)
data Thing = Thing Int String [String]
             deriving (Eq, Show)
-- Record syntax (note: no trailing comma allowed)
data Thing = Thing {
          customerID :: CustomerID,
          customerName :: String,
          customerAddress :: [String]
        } deriving (Eq, Show)
-- Create values using either named fields:
myThing = Thing { customerID = 1234, customerName = "Jane", customerAddress = ["PO Box 1"] }
-- Or anonymous, ordered fields:
myThing = Thing 1234 "John" ["1 Infinite Loop"]
-- Algebraic types with multiple value constructors
data PaymentRecord = CreditCard | CashAccount
data Color = Red | Green | Blue deriving (Eq, Show)
-- Create a synonym for an existing type
type RecordLocator = String
-- Same, but for a tuple
type ContactDetails = (Name, PhoneNumber, Address)
-- Wrap a type to present it as something else (eg. List as ZipList).
-- Can only have one value constructor, and constructor can only have one field.
newtype ZipList a = ZipList { getZipList :: [a] }
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
Type classes
-- Definition
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x == y = not (x /= y) -- note the circularity here
  x /= y = not (x == y) -- meaning that you only have to implement one
-- Making a type an instance of a type class
data MyStatus = Started | Stopped
instance Eq MyStatus where
  Started == Started = True
  Stopped == Stopped = True
  _ == _ = False
-- Types can be instances of many type classes at once
instance Show MyStatus where
  show Started = "Started"
  show Stopped = "Stopped"
-- Defining a subclass of another typeclass
-- (in order to be an instance of `Num`, you must be an instance of `Eq`)
class (Eq a) => Num where
  ...
-- Parameterized types as instances of type classes
-- (works for `Mabye Int`, `Maybe Char`, `Maybe Something` etc,
-- as long as `Something` is an instance of the `Eq` typeclass)
instance (Eq m) => Eq (Maybe m) where
  Just x == Just y = x == y
  Nothing == Nothing = true
  _ == _ = False
-- Show instances of a type class
:info Maybe
Pattern matching
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Pragmas
.|. :: Bits a => a -> a -> a.&. :: Bits a => a -> a -> ashiftL :: Bits a => a -> Int -> ashiftR :: Bits a => a -> Int -> aData.Char
digitToInt::Char -> Intord::Char -> InttoUpper::Char -> Char
Data.List
isInfixOf :: Eq a => [a] -> [a] -> Bool 
isPrefixOf :: Eq a => [a] -> [a] -> Bool 
isSuffixOf :: Eq a => [a] -> [a] -> Bool 
tails :: [a] -> [[a]] … returns all tails of a list 
Data.ratio
% :: Integral a => a -> a -> Ratio a 
Debug.Trace
trace :: String -> a -> a 
traceM :: String -> m () (for use in do notation) 
Numeric
showHex :: (Integral a, Show a) => a -> ShowS 
Syntax
--: begin a single-line comment 
{- ... -}: in-line comment 
if/then/else: conditional expression 
$: function application (low precedence) 
.: function composition ((f . g) x is same as f (g x)). 
let + in: create bound variables with the scope of an expression 
where: like let, but at top level of equation; not an expression 
case (something) of (pattern) -> expression: pattern matching within expressions 
|: guard (additionally restricts a pattern match) 
`fn` (backticks): apply fn in infix position 
foo@(x:xs) ("as-pattern"): refer to entirety of pattern match contents 
::: disambiguate a type (eg. read "5" :: Double) 
Importing modules
import Data.Set -- import everything from Data.Set (unqualified dump into top-level scope)
import Data.Set (member, union) -- import only named bindings
import qualified Data.Set -- import everything, but bound as Data.Set.{name}
import qualified Data.Set as Set -- import using an alias Set.{name}
import qualified Data.Set as Set (member, union) -- partial, aliased, qualified import
Defining modules
-- Simple: Foo.hs
module Foo (bar, baz) where
  bar = 1
  baz = id
-- Nested: Bar/Baz.hs
module Bar.Baz (
  , Thing -- export (abstract/opaque) type but not constructor(s)
  , Other(..) -- exports type and constructors (for pattern matching etc)
  , x
  ) where
  data Thing = Thing Int
  data Other = Other String
  x = 2
Types
Double: double-precision floating point. 
Float: single-precision floating point. 
Int: fixed precision signed integer (bounds are architecture-dependent and given by maxBound :: Int and minBound :: Int). 
Word: fixed precision unsigned integer (bounds: minBound :: Word — ie. 0 — and maxBound :: Word). 
Integer: arbitrary precision integer. 
Defining new types
-- "Thing" type constructor (for pattern matching)
-- "Thing" value constructor (for creating values of the type)
data Thing = Thing Int String [String]
             deriving (Eq, Show)
-- Record syntax (note: no trailing comma allowed)
data Thing = Thing {
          customerID :: CustomerID,
          customerName :: String,
          customerAddress :: [String]
        } deriving (Eq, Show)
-- Create values using either named fields:
myThing = Thing { customerID = 1234, customerName = "Jane", customerAddress = ["PO Box 1"] }
-- Or anonymous, ordered fields:
myThing = Thing 1234 "John" ["1 Infinite Loop"]
-- Algebraic types with multiple value constructors
data PaymentRecord = CreditCard | CashAccount
data Color = Red | Green | Blue deriving (Eq, Show)
-- Create a synonym for an existing type
type RecordLocator = String
-- Same, but for a tuple
type ContactDetails = (Name, PhoneNumber, Address)
-- Wrap a type to present it as something else (eg. List as ZipList).
-- Can only have one value constructor, and constructor can only have one field.
newtype ZipList a = ZipList { getZipList :: [a] }
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
Type classes
-- Definition
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x == y = not (x /= y) -- note the circularity here
  x /= y = not (x == y) -- meaning that you only have to implement one
-- Making a type an instance of a type class
data MyStatus = Started | Stopped
instance Eq MyStatus where
  Started == Started = True
  Stopped == Stopped = True
  _ == _ = False
-- Types can be instances of many type classes at once
instance Show MyStatus where
  show Started = "Started"
  show Stopped = "Stopped"
-- Defining a subclass of another typeclass
-- (in order to be an instance of `Num`, you must be an instance of `Eq`)
class (Eq a) => Num where
  ...
-- Parameterized types as instances of type classes
-- (works for `Mabye Int`, `Maybe Char`, `Maybe Something` etc,
-- as long as `Something` is an instance of the `Eq` typeclass)
instance (Eq m) => Eq (Maybe m) where
  Just x == Just y = x == y
  Nothing == Nothing = true
  _ == _ = False
-- Show instances of a type class
:info Maybe
Pattern matching
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Pragmas
isInfixOf :: Eq a => [a] -> [a] -> BoolisPrefixOf :: Eq a => [a] -> [a] -> BoolisSuffixOf :: Eq a => [a] -> [a] -> Booltails :: [a] -> [[a]] … returns all tails of a list%::Integral a => a -> a -> Ratio a
Debug.Trace
trace :: String -> a -> a 
traceM :: String -> m () (for use in do notation) 
Numeric
showHex :: (Integral a, Show a) => a -> ShowS 
Syntax
--: begin a single-line comment 
{- ... -}: in-line comment 
if/then/else: conditional expression 
$: function application (low precedence) 
.: function composition ((f . g) x is same as f (g x)). 
let + in: create bound variables with the scope of an expression 
where: like let, but at top level of equation; not an expression 
case (something) of (pattern) -> expression: pattern matching within expressions 
|: guard (additionally restricts a pattern match) 
`fn` (backticks): apply fn in infix position 
foo@(x:xs) ("as-pattern"): refer to entirety of pattern match contents 
::: disambiguate a type (eg. read "5" :: Double) 
Importing modules
import Data.Set -- import everything from Data.Set (unqualified dump into top-level scope)
import Data.Set (member, union) -- import only named bindings
import qualified Data.Set -- import everything, but bound as Data.Set.{name}
import qualified Data.Set as Set -- import using an alias Set.{name}
import qualified Data.Set as Set (member, union) -- partial, aliased, qualified import
Defining modules
-- Simple: Foo.hs
module Foo (bar, baz) where
  bar = 1
  baz = id
-- Nested: Bar/Baz.hs
module Bar.Baz (
  , Thing -- export (abstract/opaque) type but not constructor(s)
  , Other(..) -- exports type and constructors (for pattern matching etc)
  , x
  ) where
  data Thing = Thing Int
  data Other = Other String
  x = 2
Types
Double: double-precision floating point. 
Float: single-precision floating point. 
Int: fixed precision signed integer (bounds are architecture-dependent and given by maxBound :: Int and minBound :: Int). 
Word: fixed precision unsigned integer (bounds: minBound :: Word — ie. 0 — and maxBound :: Word). 
Integer: arbitrary precision integer. 
Defining new types
-- "Thing" type constructor (for pattern matching)
-- "Thing" value constructor (for creating values of the type)
data Thing = Thing Int String [String]
             deriving (Eq, Show)
-- Record syntax (note: no trailing comma allowed)
data Thing = Thing {
          customerID :: CustomerID,
          customerName :: String,
          customerAddress :: [String]
        } deriving (Eq, Show)
-- Create values using either named fields:
myThing = Thing { customerID = 1234, customerName = "Jane", customerAddress = ["PO Box 1"] }
-- Or anonymous, ordered fields:
myThing = Thing 1234 "John" ["1 Infinite Loop"]
-- Algebraic types with multiple value constructors
data PaymentRecord = CreditCard | CashAccount
data Color = Red | Green | Blue deriving (Eq, Show)
-- Create a synonym for an existing type
type RecordLocator = String
-- Same, but for a tuple
type ContactDetails = (Name, PhoneNumber, Address)
-- Wrap a type to present it as something else (eg. List as ZipList).
-- Can only have one value constructor, and constructor can only have one field.
newtype ZipList a = ZipList { getZipList :: [a] }
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
Type classes
-- Definition
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x == y = not (x /= y) -- note the circularity here
  x /= y = not (x == y) -- meaning that you only have to implement one
-- Making a type an instance of a type class
data MyStatus = Started | Stopped
instance Eq MyStatus where
  Started == Started = True
  Stopped == Stopped = True
  _ == _ = False
-- Types can be instances of many type classes at once
instance Show MyStatus where
  show Started = "Started"
  show Stopped = "Stopped"
-- Defining a subclass of another typeclass
-- (in order to be an instance of `Num`, you must be an instance of `Eq`)
class (Eq a) => Num where
  ...
-- Parameterized types as instances of type classes
-- (works for `Mabye Int`, `Maybe Char`, `Maybe Something` etc,
-- as long as `Something` is an instance of the `Eq` typeclass)
instance (Eq m) => Eq (Maybe m) where
  Just x == Just y = x == y
  Nothing == Nothing = true
  _ == _ = False
-- Show instances of a type class
:info Maybe
Pattern matching
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Pragmas
trace :: String -> a -> atraceM :: String -> m () (for use in do notation)Numeric
showHex::(Integral a, Show a) => a -> ShowS
Syntax
--: begin a single-line comment 
{- ... -}: in-line comment 
if/then/else: conditional expression 
$: function application (low precedence) 
.: function composition ((f . g) x is same as f (g x)). 
let + in: create bound variables with the scope of an expression 
where: like let, but at top level of equation; not an expression 
case (something) of (pattern) -> expression: pattern matching within expressions 
|: guard (additionally restricts a pattern match) 
`fn` (backticks): apply fn in infix position 
foo@(x:xs) ("as-pattern"): refer to entirety of pattern match contents 
::: disambiguate a type (eg. read "5" :: Double) 
Importing modules
import Data.Set -- import everything from Data.Set (unqualified dump into top-level scope)
import Data.Set (member, union) -- import only named bindings
import qualified Data.Set -- import everything, but bound as Data.Set.{name}
import qualified Data.Set as Set -- import using an alias Set.{name}
import qualified Data.Set as Set (member, union) -- partial, aliased, qualified import
Defining modules
-- Simple: Foo.hs
module Foo (bar, baz) where
  bar = 1
  baz = id
-- Nested: Bar/Baz.hs
module Bar.Baz (
  , Thing -- export (abstract/opaque) type but not constructor(s)
  , Other(..) -- exports type and constructors (for pattern matching etc)
  , x
  ) where
  data Thing = Thing Int
  data Other = Other String
  x = 2
Types
Double: double-precision floating point. 
Float: single-precision floating point. 
Int: fixed precision signed integer (bounds are architecture-dependent and given by maxBound :: Int and minBound :: Int). 
Word: fixed precision unsigned integer (bounds: minBound :: Word — ie. 0 — and maxBound :: Word). 
Integer: arbitrary precision integer. 
Defining new types
-- "Thing" type constructor (for pattern matching)
-- "Thing" value constructor (for creating values of the type)
data Thing = Thing Int String [String]
             deriving (Eq, Show)
-- Record syntax (note: no trailing comma allowed)
data Thing = Thing {
          customerID :: CustomerID,
          customerName :: String,
          customerAddress :: [String]
        } deriving (Eq, Show)
-- Create values using either named fields:
myThing = Thing { customerID = 1234, customerName = "Jane", customerAddress = ["PO Box 1"] }
-- Or anonymous, ordered fields:
myThing = Thing 1234 "John" ["1 Infinite Loop"]
-- Algebraic types with multiple value constructors
data PaymentRecord = CreditCard | CashAccount
data Color = Red | Green | Blue deriving (Eq, Show)
-- Create a synonym for an existing type
type RecordLocator = String
-- Same, but for a tuple
type ContactDetails = (Name, PhoneNumber, Address)
-- Wrap a type to present it as something else (eg. List as ZipList).
-- Can only have one value constructor, and constructor can only have one field.
newtype ZipList a = ZipList { getZipList :: [a] }
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
Type classes
-- Definition
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x == y = not (x /= y) -- note the circularity here
  x /= y = not (x == y) -- meaning that you only have to implement one
-- Making a type an instance of a type class
data MyStatus = Started | Stopped
instance Eq MyStatus where
  Started == Started = True
  Stopped == Stopped = True
  _ == _ = False
-- Types can be instances of many type classes at once
instance Show MyStatus where
  show Started = "Started"
  show Stopped = "Stopped"
-- Defining a subclass of another typeclass
-- (in order to be an instance of `Num`, you must be an instance of `Eq`)
class (Eq a) => Num where
  ...
-- Parameterized types as instances of type classes
-- (works for `Mabye Int`, `Maybe Char`, `Maybe Something` etc,
-- as long as `Something` is an instance of the `Eq` typeclass)
instance (Eq m) => Eq (Maybe m) where
  Just x == Just y = x == y
  Nothing == Nothing = true
  _ == _ = False
-- Show instances of a type class
:info Maybe
Pattern matching
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Pragmas
--: begin a single-line comment{- ... -}: in-line commentif/then/else: conditional expression$: function application (low precedence).: function composition ((f . g) x is same as f (g x)).let + in: create bound variables with the scope of an expressionwhere: like let, but at top level of equation; not an expressioncase (something) of (pattern) -> expression: pattern matching within expressions|: guard (additionally restricts a pattern match)`fn` (backticks): apply fn in infix positionfoo@(x:xs) ("as-pattern"): refer to entirety of pattern match contents::: disambiguate a type (eg. read "5" :: Double)import Data.Set -- import everything from Data.Set (unqualified dump into top-level scope)
import Data.Set (member, union) -- import only named bindings
import qualified Data.Set -- import everything, but bound as Data.Set.{name}
import qualified Data.Set as Set -- import using an alias Set.{name}
import qualified Data.Set as Set (member, union) -- partial, aliased, qualified import
Defining modules
-- Simple: Foo.hs
module Foo (bar, baz) where
  bar = 1
  baz = id
-- Nested: Bar/Baz.hs
module Bar.Baz (
  , Thing -- export (abstract/opaque) type but not constructor(s)
  , Other(..) -- exports type and constructors (for pattern matching etc)
  , x
  ) where
  data Thing = Thing Int
  data Other = Other String
  x = 2
Types
Double: double-precision floating point. 
Float: single-precision floating point. 
Int: fixed precision signed integer (bounds are architecture-dependent and given by maxBound :: Int and minBound :: Int). 
Word: fixed precision unsigned integer (bounds: minBound :: Word — ie. 0 — and maxBound :: Word). 
Integer: arbitrary precision integer. 
Defining new types
-- "Thing" type constructor (for pattern matching)
-- "Thing" value constructor (for creating values of the type)
data Thing = Thing Int String [String]
             deriving (Eq, Show)
-- Record syntax (note: no trailing comma allowed)
data Thing = Thing {
          customerID :: CustomerID,
          customerName :: String,
          customerAddress :: [String]
        } deriving (Eq, Show)
-- Create values using either named fields:
myThing = Thing { customerID = 1234, customerName = "Jane", customerAddress = ["PO Box 1"] }
-- Or anonymous, ordered fields:
myThing = Thing 1234 "John" ["1 Infinite Loop"]
-- Algebraic types with multiple value constructors
data PaymentRecord = CreditCard | CashAccount
data Color = Red | Green | Blue deriving (Eq, Show)
-- Create a synonym for an existing type
type RecordLocator = String
-- Same, but for a tuple
type ContactDetails = (Name, PhoneNumber, Address)
-- Wrap a type to present it as something else (eg. List as ZipList).
-- Can only have one value constructor, and constructor can only have one field.
newtype ZipList a = ZipList { getZipList :: [a] }
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
Type classes
-- Definition
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x == y = not (x /= y) -- note the circularity here
  x /= y = not (x == y) -- meaning that you only have to implement one
-- Making a type an instance of a type class
data MyStatus = Started | Stopped
instance Eq MyStatus where
  Started == Started = True
  Stopped == Stopped = True
  _ == _ = False
-- Types can be instances of many type classes at once
instance Show MyStatus where
  show Started = "Started"
  show Stopped = "Stopped"
-- Defining a subclass of another typeclass
-- (in order to be an instance of `Num`, you must be an instance of `Eq`)
class (Eq a) => Num where
  ...
-- Parameterized types as instances of type classes
-- (works for `Mabye Int`, `Maybe Char`, `Maybe Something` etc,
-- as long as `Something` is an instance of the `Eq` typeclass)
instance (Eq m) => Eq (Maybe m) where
  Just x == Just y = x == y
  Nothing == Nothing = true
  _ == _ = False
-- Show instances of a type class
:info Maybe
Pattern matching
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Pragmas
-- Simple: Foo.hs
module Foo (bar, baz) where
  bar = 1
  baz = id
-- Nested: Bar/Baz.hs
module Bar.Baz (
  , Thing -- export (abstract/opaque) type but not constructor(s)
  , Other(..) -- exports type and constructors (for pattern matching etc)
  , x
  ) where
  data Thing = Thing Int
  data Other = Other String
  x = 2
Double: double-precision floating point.Float: single-precision floating point.Int: fixed precision signed integer (bounds are architecture-dependent and given bymaxBound :: IntandminBound :: Int).Word: fixed precision unsigned integer (bounds:minBound :: Word— ie. 0 — andmaxBound :: Word).Integer: arbitrary precision integer.
Defining new types
-- "Thing" type constructor (for pattern matching)
-- "Thing" value constructor (for creating values of the type)
data Thing = Thing Int String [String]
             deriving (Eq, Show)
-- Record syntax (note: no trailing comma allowed)
data Thing = Thing {
          customerID :: CustomerID,
          customerName :: String,
          customerAddress :: [String]
        } deriving (Eq, Show)
-- Create values using either named fields:
myThing = Thing { customerID = 1234, customerName = "Jane", customerAddress = ["PO Box 1"] }
-- Or anonymous, ordered fields:
myThing = Thing 1234 "John" ["1 Infinite Loop"]
-- Algebraic types with multiple value constructors
data PaymentRecord = CreditCard | CashAccount
data Color = Red | Green | Blue deriving (Eq, Show)
-- Create a synonym for an existing type
type RecordLocator = String
-- Same, but for a tuple
type ContactDetails = (Name, PhoneNumber, Address)
-- Wrap a type to present it as something else (eg. List as ZipList).
-- Can only have one value constructor, and constructor can only have one field.
newtype ZipList a = ZipList { getZipList :: [a] }
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
Type classes
-- Definition
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x == y = not (x /= y) -- note the circularity here
  x /= y = not (x == y) -- meaning that you only have to implement one
-- Making a type an instance of a type class
data MyStatus = Started | Stopped
instance Eq MyStatus where
  Started == Started = True
  Stopped == Stopped = True
  _ == _ = False
-- Types can be instances of many type classes at once
instance Show MyStatus where
  show Started = "Started"
  show Stopped = "Stopped"
-- Defining a subclass of another typeclass
-- (in order to be an instance of `Num`, you must be an instance of `Eq`)
class (Eq a) => Num where
  ...
-- Parameterized types as instances of type classes
-- (works for `Mabye Int`, `Maybe Char`, `Maybe Something` etc,
-- as long as `Something` is an instance of the `Eq` typeclass)
instance (Eq m) => Eq (Maybe m) where
  Just x == Just y = x == y
  Nothing == Nothing = true
  _ == _ = False
-- Show instances of a type class
:info Maybe
Pattern matching
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Pragmas
-- "Thing" type constructor (for pattern matching)
-- "Thing" value constructor (for creating values of the type)
data Thing = Thing Int String [String]
             deriving (Eq, Show)
-- Record syntax (note: no trailing comma allowed)
data Thing = Thing {
          customerID :: CustomerID,
          customerName :: String,
          customerAddress :: [String]
        } deriving (Eq, Show)
-- Create values using either named fields:
myThing = Thing { customerID = 1234, customerName = "Jane", customerAddress = ["PO Box 1"] }
-- Or anonymous, ordered fields:
myThing = Thing 1234 "John" ["1 Infinite Loop"]
-- Algebraic types with multiple value constructors
data PaymentRecord = CreditCard | CashAccount
data Color = Red | Green | Blue deriving (Eq, Show)
-- Create a synonym for an existing type
type RecordLocator = String
-- Same, but for a tuple
type ContactDetails = (Name, PhoneNumber, Address)
-- Wrap a type to present it as something else (eg. List as ZipList).
-- Can only have one value constructor, and constructor can only have one field.
newtype ZipList a = ZipList { getZipList :: [a] }
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
-- Definition
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x == y = not (x /= y) -- note the circularity here
  x /= y = not (x == y) -- meaning that you only have to implement one
-- Making a type an instance of a type class
data MyStatus = Started | Stopped
instance Eq MyStatus where
  Started == Started = True
  Stopped == Stopped = True
  _ == _ = False
-- Types can be instances of many type classes at once
instance Show MyStatus where
  show Started = "Started"
  show Stopped = "Stopped"
-- Defining a subclass of another typeclass
-- (in order to be an instance of `Num`, you must be an instance of `Eq`)
class (Eq a) => Num where
  ...
-- Parameterized types as instances of type classes
-- (works for `Mabye Int`, `Maybe Char`, `Maybe Something` etc,
-- as long as `Something` is an instance of the `Eq` typeclass)
instance (Eq m) => Eq (Maybe m) where
  Just x == Just y = x == y
  Nothing == Nothing = true
  _ == _ = False
-- Show instances of a type class
:info Maybe
Pattern matching
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Pragmas
-- Multiple function definitions matching on type constructors
sumList (x:xs) = x + sumList xs
sumList [] = 0
-- Note we could also have written that last one as:
sumList _ = 0
Enabled with {-# LANGUAGE p1, p2... #-}, where p1, p2 etc are drawn from:
TypeSynonymInstances: Allow specialized polymorphic types (eg.Stringor[Char]) to be instances of a typeclass (as opposed to just[a]).OverlappingInstances: Given two instances that overlap (eg.[a]and[String]), choose the more specific one.
Functors (Functor typeclass)
Implement fmap :: (a -> b) -> f a -> f b and comply with the two functor laws:
fmap idmust equalid.fmap (p . q)must equal(fmap p) . (fmap q).
In plain English, a functor is a value in a "context", supporting an fmap operation for applying a function to the value while preserving that "context". The second functor law means that we can freely compose functions and apply them using fmap, or compose the results of applying fmap to functions, and get the same result.
Example functors:
- Lists.
 - Functions.
 Maybe.
Applicative functors (Applicative typeclass)
These are functors where the value itself can be applied (ie. they are functions in a "context").
- Implement 
pure(wraps value in applicative). - Implement 
<*>, pronounced "apply" ((Applicative f) => f (a -> b) -> f a -> f b). - Additionally, 
<$>, pronounced "fmap": this is an infixfmap. - Note that all applicatives are functors.
 
Example applicative functors:
- Lists.
 Maybe.Options.Applicative(from the optparse-applicative package).- The aeson JSON parser.
 
Monoids (Monoid typeclass)
- Implement a 
mappend binary function (m -> m -> m). 
- The function must be associative (ie. 
(3 + 4) + 5 is equivalent to 3 + (4 + 5)). 
- There must be an identity value (
mempty) that when applied to either side of the function returns the other value unmodified. 
- Implement an 
mconcat ([m] -> m) function that flattens (eg. foldr mappend mempty). 
mappend binary function (m -> m -> m).(3 + 4) + 5 is equivalent to 3 + (4 + 5)).mempty) that when applied to either side of the function returns the other value unmodified.mconcat ([m] -> m) function that flattens (eg. foldr mappend mempty).Example monoids:
- Lists.
 Product(ie.Numnewtypewithmempty:1andmappend:*).Sum(ie.Numnewtypewithmempty:0andmappend:+).Any(ie.Boolwithmempty:Falseandmappend:||).All(ie.Boolwithmempty:Trueandmappend:&&).Ordering.Maybe.
Monads
Applicative functors (enforced by type constraint as of GHC 7.10) that additionally define >>=, or "bind" (ie. (Monad m) => m a -> (a -> m b) -> m b).
Example monads:
Either.Maybe.Either.[].IO.