Skip to content

Latest commit

 

History

History
79 lines (72 loc) · 4.7 KB

haskell.md

File metadata and controls

79 lines (72 loc) · 4.7 KB
  • Integers and Strings are still 5 and "chris". No weird syntax so far.
  • Strings are lists of Chars. You can make them by consing many Chars together if you want.
  • 5 is an expression. Its value is 5.
  • /= appears to mean "not equal".
  • sort [1,2,3] sorts values ascending. So, that does nothing.
  • sort "abc" also works.
  • There are tuples: (). Tuples look the same as ones in Python. This means function calls are not wrapped in parens.
  • fst (1,2) gets the first item, 1, apparently.
  • let var = expression in body creates a local scope. It assigns nothing to var. That is to say,
let x = 8 * 10 in x + x      # with (x = 80)
=> 160                       #    yield x + x
  • The cons (unshift) function: (:). 'a' : [] means [] cons 'a', which yields ["a"]. Whitespace between : does not matter.
  • That is, a : b means (cons a b).
  • Likewise, 'a' : 'b' : [] is just "given [], cons b, then cons a". Imagine parentheses.
  • Now that : means cons, 0:[1, 2] equals [0, 1, 2].
  • You can build an empty list by consing a bunch of stuff to [], e.g. 1:2:3:[] == [1, 2, 3]
  • Lists must contain items of the same type.
  • == compares equality. Err, ['1', '2', '3'] == '123'.
  • map (+1) [1..5] does exactly what it reads.
  • $ ghci gives you Prelude>. o_O
  • Hugs is faster than GHC, but doesn't allow function definitions in the environment. (That is to say, it is not complete.)
  • Haskell is a lazy language, where nothing is computed unless it is forced to. That is useful for dealing with 'infinite' things like a list from 0 to infinity.
  • Lazy languages in general call by name, instead of call by value.
  • Haskell is case-sensitive. "Haskell actually uses case to give meaning."
  • That is, variables/functions must begin in lower case, and types must begin in upper case.
  • Strings are not the same as characters. Like Java, they differentiate literally by double and single quotes.
  • Pure functions are functions without side effects. A stricter sense of it is if the function always produces the same result.
  • Variables are not memory addresses; they are names. You cannot make something else called that (e.g. x = x + 1 is illegal); that which was named was that.
  • Referential Transparency: because Haskell is so strict, that if two functions produce the same result, the two functions are interchangeable.
  • (sqrt 2), sqrt 2, and sqrt(2) all produce the same result. "Even though parentheses are not always needed, sometimes it is better to leave them in anyway; other people will probably have to read your code"
  • There seems to be no limit to the size of a number (try 2^5000), but there is a limit to the number of decimal points (try 1/that number)
  • The 3-item term for tuple is triple.
  • head and tail is Haskell's way of saying first and rest in Scheme.
  • Concatenation. "Hello " ++ "World" == "Hello World"
  • show() turns anything into Strings.
  • read() turns strings into anything. HOWEVER, it does so only if it knows what to convert to, say read("123") + 1 == 124
  • foldr()? reduceRight. foldl()? reduce. Reduce is probably what you had in mind.
  • foldr (-) 1 [4, 8, 5] = 4 - (foldr (-) 1 [8, 5]) = 4 - (8 - (5 - foldr (-) 1 [])) = (4 - (8 - (5 - 1)) = 0
  • foldl is faster, but foldr can work with infinite lists (????)
  • In a file, module Foo where defines a module called Foo.
  • :l Foo loads module Foo.
  • A standalone program Main must have a method main inside it. However, the file need not be "Main.hs".
  • ghc Foo.hs only compiles a Foo.hi file. You need ghc --make Foo.hs -o foo. After that, Test is an executable.
  • square x = x * x means "square is a function that takes x in and returns x * x".
  • If conditionals are done in line-broken one-liners. foo x = if x < 0 then -1 else 2
  • -1 cannot be used as a function parameter because foo -1 could have meant foo - 1. Use foo(-1) instead.
  • It is impossible to have an if statement with no else.
  • Switch cases, what they look like, and what _ means in them.
f x =
    case x of {
        0 -> 1;
        1 -> 5;
        2 -> 2;
        _ -> -1
    }

(braces, semicolons optional but encouraged)
  • Tabs and space indentations are actually encouraged to be 8 spaces long.
  • Functions can be defined piecewise, a bit like overloading.
foo 0 = 1
foo 1 = 3
foo 2 = 9001
foo _ = 0
  • (foo . bar) 123 is mathematical notation for foo(bar(123)).
  • null lst checks if a list lst is empty.
  • >>= is the bind operator (monads, composition)
  • Haskell's lazy evaluation works by maintaining a graph of past evaluations, reducing the execution graph by inputs and outputs. It can do so because Haskell is pure functional.