[TOC]
-- Prefix notation:
div 10 6
(+) 1 2
-- Infix notation
10 `div` 6
1 + 2
-- let
foo x =
let y = x * 2
z = x ^ 2
in 2 * y * z
-- where
foo x = 2 * y *z
where y = x * 2
z = x ^ 2
-- Write a string to std out
putStr :: String -> IO ()
-- Write a string to std out, add a newline character
putStrLn :: String -> IO ()
data Bool = False | True
-- [1] [2] [3]
- Type constructor
- Data constructor
|
defines a sum type
Int
: fixed-precision integer.Integer
: ubounded integer.
Float
Double
Rational
: ratio of two integers. For example,1 / 2 :: Rational
These are datatypes that allow to carry multiple values within a single value. Size and types of tuple elements are determined by the type of the tuple. I.e., (a, b)
is a pair of values of types a
and b
, (a, b, c)
is a triple, etc.
data (,) a b = (,) a b -- this is the definition of pair
-- Exmaples of creating tuples:
(,) 8 9
(7, "Abc")
-- Functions to get first and second value of a pair:
fst :: (a, b) -> a
snd :: (a, b) -> b
-- Swap values of a pair:
swap :: (a, b) -> (b, a)
Lists also contain multiple values within a single value. All elements are of the same type. The number of elements is not fixed by the type.
l :: [Int] -- a list of Ints
l = [1, 2, 3] -- a list with three elements
-- Concat two lists
(++) :: [a] -> [a] -> [a]
-- Concat a list of lists
concat :: [[a]] -> [a]
-- Length of a list
length :: [a] -> Int
-- Reverse a list
reverse :: [a] -> [a]
The arrow, (->)
, is a type constructor for functions. It has not data constructors. Fuctions are values.
data (->) a b
All functions in Haskell take one argument and return one result. Currying refers to nesting multiple functions, each accepting one argument and returning one result.
f :: a -> a -> a
-- (->) is right associative, so this is equivalent to
f :: a -> (a -> a)
Thus, functions with more than one argument can be partially applied.
There are curry
and uncurry
functions. curry
takes a function of one argument that takes a tuple ((a, b) -> c
) and produces a function that takes two arguments sequentially (a -> b -> c
). uncurry
does the opposite.
curry :: ((a, b) -> c) -> (a -> b -> c)
uncurry :: (a -> b -> c) -> ((a, b) -> c)
Sectioning is a partial application of infix operators.
(6/) -- (/) operator partially applied to value 6 as first argument.
(/6) -- same, but 6 now is second argument
(6/) 3 == 2 -- True
(/6) 18 == 18 -- True
todo: defining typeclasses and instaces
Typeclass that allows to test two values for equality.
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
Typeclass implemented by most numeric types.
class Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
instance Num Integer
instance Num Int
instance Num Float
instance Num Double
Known instances: Integer, Int, Float, Double
class (Real a, Enum a) => Integral a where
quot :: a -> a -> a
rem :: a -> a -> a
div :: a -> a -> a
mod :: a -> a -> a
quotRem :: a -> a -> (a, a)
divMod :: a -> a -> (a, a)
toInteger :: a -> Integer
instance Integral Int
instance Integral Integer
class (Num a) => Fractional a where
(/) :: a -> a -> a
recip :: a -> a
fromRational :: Rational -> a
Type class for all types that has order defined.
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
(>=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(<=) :: a -> a -> Bool
max :: a -> a -> a
min :: a -> a -> a
data Ordering = LT | EQ | GT
instance Ord a => Ord (Maybe a)
instance (Ord a, Ord b) => Ord (Either a b)
instance Ord Integer
instance Ord a => Ord [a]
instance Ord Ordering
instance Ord Int
instance Ord Float
instance Ord Double
instance Ord Char
instance Ord Bool
Typeclass for enumerable types, i.e. for each value there are known successor and predecessor.
class Enum a where
succ :: a -> a
pred :: a -> a
toEnum :: Int -> a -- take a value by its ordinal number
fromEnum :: a -> Int -- get the ordinal number of a value
enumFrom :: a -> [a] -- a list of values, starting from certain value
enumFromThen :: a -> a -> [a] -- a list of values, starting from a certain value, followed by another value. for instance `enumFromThen 1 3` will give [1, 3, 5, ...]
enumFromTo :: a -> a -> [a]
enumFromThenTo :: a -> a -> a -> [a]
class Show a where
showsPrec :: Int -> a -> ShowS
show :: a -> String
showList :: [a] -> ShowS
instance Show a => Show [a]
instance Show Ordering
instance Show a => Show (Maybe a)
instance Show Integer
instance Show Int
instance Show Char
instance Show Bool
instance Show ()
instance Show Float
instance Show Double
default Num Integer
default Real Integer
default Enum Integer
default Integral Integer
default Fractional Double
default RealFrac Double
default Floating Double
default RealFloat Double
data Mood = Blah deriving (Eq, Show)
Typeclasses that support deriving:
Eq, Ord, Enum, Bounded, Read, Show
-- definition
(\x -> x * 3) :: Integer -> Integer
(\x y -> x + y) :: Integer -> Integer
-- application (function applied to value 5)
(\x -> x * 3) 5
(\x y -> x + y) x y
if <condition>
then <result if True>
else <result if False>
funcZ x =
case x + 1 == 1 of
True -> "AWESOME"
False -> "wut"
myAbs :: Integer -> Integer
myAbs x
| x < 0 = (-x)
| otherwise = x
-- composition operator
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
-- usage
(f . g) x = f (g x)
-- examples
take 5 . reverse $ [1..10] = [10, 9, 8, 7, 6]
take 5 . filter odd . enumFrom $ 3 = [3, 5, 7, 9, 11]
⊥ or bottom refers to computations that do not result in a value. The two main varieties of bottom are computations that failed with an error or those that failed to terminate.
Examples of bottom:
- Non-terminating
Prelude> let x = x in x
- Error
f :: Bool -> Int
f True = error "blah"
f False = 0
-- this is bottom:
f True
- Partial function:
f :: Bool -> Int
f False = 0
-- this is bottom