haskell

#define haskell: \ I------------------------------------------------------------------\ I------------------------------------------------------------------\ I------------------------------------------------------------------\ I /$$ /$$ /$$ /$$ /$$ \ I | $$ | $$ | $$ | $$| $$ \ I | $$ | $$ /$$$$$$ /$$$$$$$| $$ /$$ /$$$$$$ | $$| $$ \ I | $$$$$$$$ |____ $$ /$$_____/| $$ /$$/ /$$__ $$| $$| $$ \ I | $$__ $$ /$$$$$$$| $$$$$$ | $$$$$$/ | $$$$$$$$| $$| $$ \ I | $$ | $$ /$$__ $$ \____ $$| $$_ $$ | $$_____/| $$| $$ \ I | $$ | $$| $$$$$$$ /$$$$$$$/| $$ \ $$| $$$$$$$| $$| $$ \ I |__/ |__/ \_______/|_______/ |__/ \__/ \_______/|__/|__/ \ I------------------------------------------------------------------\ I------------------------------------------------------------------\ I------------------------------------------------------------------I PROGRAMS: ghc : haskell compiler ghci : haskell interpreter; eval-s each statement in its own module /*?!*/ <statement> :<meta> l : load r : reload q : quit i <subject> : print info !<command> : execute <command> in a system shell cabal : haskell dependency and project manager init run install COMMENTING: -- <...> : single line {- <...> -} : multi line OPERATORS: <oper-1> <operator> <oper-2> : apply <operator> to operands <oper-x> (<operator>) <oper-1> <oper-2> : apply <operator> to operands <oper-x>; prefix syntax <func-1> $ <func-2> : apply operator; equivalent to <func-1>(<func-2>) FUNCTIONS: <name> <arg>+ = <body> { f x = x + 1 } Signature: • not required • enforces types <name> :: (constraint) <type-signature> constraint: <typename> <alias> => : alias <alias> as <typename> for the type signature { // f :: Num a => a -> a } type_signature: <typename> -> <typename> Calling: <name> <arg>* Body: <expression> <let_binding> in <expression> <expression> where <where_binding> Bindings: • defines intermediate values • similar to vars Let: { in_range min max x = let l = x >= min h = x <= max in l && h } Where: { in_rr2 min max x = l && h where l = x >= min h = x <= max } Currying: • every function technically takes one argument • multi argument functions eval to a function with one argument hardcoded { ghci> curryer a b = a / b ghci> curryer 6 / 3 2.0 ghci> intermediate_fun = curryer 6 -- intermediate_fun b = 6 / b ghci> intermediate_fun 3 2.0 } Lambdas: (\<arg>+ -> <body>) { • (\x -> 2 * x) 4 8 } CONDITIONALS: if: if <...> then <...> else <...> Pattern_matching: • top to bottom • a way to branch • similar to both switch cases and function overloading from imperative languages { // this sucessfully return the sum of all numbers from n to 0 sumt 0 = 0 sumt n = n + sumt (n - 1) // translates roughly to this: /* int sumt(int n) { * switch(n) { * case 0: * return 0; * default: * return n + sumt(n - 1); * } * } */ // this messes up the pattern matching; // causing always the top line to be called, // resulting and infinit recursive loop, // causing a stack overflow sumt n = n + sumt (n - 1) sumt 0 = 0 } Guards: <name> args+ <guard>+ (| <condition> = <body>) { f x | x < 10 = print "This is a" | x > 10 = print "very poor" | otherwise = print "example." } • checked from top to bottom • the body of the first true condition is eval-ed • "otherwise" is a special alias for true, helping readability • concentrated pattern matching in a way Types: Aliasing: type <alias> = <typename> Constraints: Eq Ord Show Num Monad Lists: [<elem>(, <elem>)*] Comprehensions: [<Int-1>..<Int-2>] -> [Int] [<Char>..<Char>] -> [Char] [<select> | <from>(, <where>)] { [i | i <- [1..10]] } Operators: <typename> : [<typename>] -> [<typename>] : concatenate an element to a list [<typename>] ++ [<typename>] -> [<typename>] : concatenate 2 lists [<typename>] !! <Int> : returns the <Int>th element Importing: import <module> (<...>) • MUST be at the beginning of the file Standard_library: Prelude head [a] -> a : returns first element tail [a] -> [a] : returns input without the first element last [a] -> a : returns last element init [a] -> [a] : returns input without the last element length [a] -> Int : returns number of elements take Int -> [a] -> [a] null [a] -> Bool elem a -> [a] -> Bool notElem a -> [a] -> BoolA any (a -> Bool) -> [a] -> Bool all (a -> Bool) -> [a] -> Bool Data.lists sum Num a => [a] -> a map (a -> b) -> [a] -> [b] sort Ord a => [a] -> [a] reverse [a] -> [a] filter (a -> Bool) -> [a] -> [a] IO putChar putStr putStrLn print