Wednesday, May 25, 2011

Haskell Syntax

(.) Function Composition
(.) :: (b -> c) -> (a -> b) -> a -> c
negate . (* 3)  returns a function that takes a number, multiplies it by 3 and then negates it
:t negate . (* 3)
negate . (* 3) :: Num c => c -> c
> let neg = negate . (* 3)
> neg 4

($) Application Operator - This operator is redundant, since ordinary application (f x) means the same as (f $ x). However, $ has low, right-associative binding precedence, so it sometimes allows parentheses to be omitted;
($) :: (a -> b) -> a -> b

Monad functions
(>>=) Bind

(>>=) :: forall a b. m a -> (a -> m b) -> m bSource
Sequentially compose two actions, passing any value produced by the first as an argument to the second.

(>>) Then
(>>) :: forall a b. m a -> m b -> m bSource
Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such as the semicolon) in imperative languages.

return :: a -> m aSource
Inject a value into the monadic type.

fail :: String -> m aSource
Fail with a message. This operation is not part of the mathematical definition of a monad, but is invoked on pattern-match failure in a do expression.


read - is sort of the opposite typeclass of Show. The read function takes a string and returns a type which is a member of Read.
read :: (Read a) => String -> a
If type can not be inferred, can use a type annotation:
let x = read "5" :: Int
Type annotations are a way of explicitly saying what the type of an expression should be. We do that by adding :: at the end of the expression and then specifying a type.
(since Haskell is a statically typed language, it has to know all the types before the code is compiled (or in the case of GHCI, evaluated).)

Enum, succ, pred 
ghci> ['a'..'e']    
ghci> succ 5

Bounded, minBound, maxBound
ghci> minBound :: Int

Num, Integral, Floating

fromIntegral :: (Integral a, Num b) => a -> b

data = typeclass
deriving = make type instance of typeclass
type = type synonym - doesn't make anything new just a synonym for existing type
class =
instance =

Lambda = closure
Basically anonymous functions that are used because we need some functions only once
We write \ because it looks like greek letter lambda) and then parameters separated by spaces, then -> then the function body.

Lambdas vs implicit currying (and partial application)
Both (+3) and (\x -> x + 3) are functions that take a number and add 3 to it
These two are the same:
addThree x y z = x + y + z
addThree = \x -> \y -> \z -> x + y + z
flip' f = \x y -> f y x
flip' f x y = f y x

(:) cons
Put something at the beginning of a list

foldl applies a binary function to a list from the left starting with an accumulator value and the left-most value of the list
foldr applies a binary function to a list from the right starting with an accumulator value and the right-most value of the list
 (the ++ function is much more expensive than : so we usually use right folds when we're building up new lists from a list.)
The foldl1 and foldr1 functions work much like foldl and foldr, only you don't need to provide them with an explicit starting value. They assume the first (or last) element of the list to be the starting value and then start the fold with the element next to it
sum = foldl1 (+)

The following are the same:
foldl (flip (:)) [] (words "hello world")
foldl (\acc x -> x : acc) [] (words "hello world")

scanl and scanr are like foldl and foldr except they show all the intermediate values in a list

Prelude> scanl (+) 0 [1,2,3,4]
Prelude> scanr (+) 0 [1,2,3,4]