Mercurial > repos > other > SevenLanguagesInSevenWeeks
diff 7-Haskell/README.txt @ 87:2b5341fc4555
Add Haskell Day 1 code and notes
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 15 Jun 2019 17:31:22 +0100 |
parents | |
children | 7e4afb129bef |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/7-Haskell/README.txt Sat Jun 15 17:31:22 2019 +0100 @@ -0,0 +1,35 @@ +Install with `zypper install ghc` for the Glasgow Haskell Compiler. The interactive shell (REPL) is `ghci`. Currently on v8.6.5 (was 6.12.1 in the book). Haskell uses strong static types with inference. + +Numbers behave like numbers. Strings have double-quotes and characters have single quotes. An array of characters (in square brackets) is a string. "+" is purely numeric addition - concatenation is "++". + +Equality is tested with "==" (equals) and "/=" (not equals - not "is divisible by"!). Haskell is strongly typed + +Indentation is significant in Haskell (like Python) BUT you can do an "if … then … else …" on a single line (however, it will assume that "if then" is a parse error, probably because functional code isn't imperative and so can't miss the else) + +Using functions on the wrong type of arguments seems to give helpful error messages along the lines of "No instance for (arg types) arising from a use of 'function' at X" (and "+" is a function). +":t val" lets you see the type of a variable or value, and ":set +t" lets you see the type of returned values. + +In code, functions are defined as "type function_name param = body". In code, that is always prefixed with "let". +Functions return the result of their last instruction. +Full function definitions are preceded by a type definition line in the form "function_name :: type(s) -> type(s)". You can also have generics and have "function_name :: (Parent_class generic_name) => generic_name -> generic_name". +Code in files needs to be in a module, which starts "module ModuleName where" on the top line. +You can then do `:load filename.hs` in the console. This then puts you in that module on the CLI (the prompt changes). + +Haskell functions can use parameter matching on arguments - see factorial.hs. + +Invoking parameters doesn't use brackets (because they're used for tuples - except when it's just a single value, when they're ignored). + +Lists can be broken up with "head" and "tail" functions (or "fst" and "snd" for tuples) *or* they can be broken up on assignment. It's like Python multi-assignment, but with colon - "(_head:_tail)" (":" is the list construction operator). It can then be used in function definitions, e.g.: + size [] = 0 + size (h:t) = 1 + size t + +Haskell can create ranges with [start..end]. Specifying an invalid range (e.g. decreasing) gives an empty list. Specifying an increment is different to all other languages: [start, next..end] (e.g. "[10, 8..4]" gives "[10, 8, 6, 4]" and it works out to decrement by 2). +You can also do (lazy) infinite ranges by not specifying an end and then using "take" functions etc to pull just the values you need. + +List comprehension is slightly pythonic: "[expr | val <- [vals] ]" where "expr" is the expression to calculate in the new list, val is a variable used in expr and [vals] is the source list. It's effectively "expression for value in list". +You can also assign multiple independent variables, possibly from the same source. For example: + let crew = ["Kirk", "Spock", "McCoy"] + [(a,b) | a <- crew, b <- crew] +calculates all combinations of crew names. Changing it to: + [(a,b) | a <- crew, b <- crew, a /= b] +lets you add filtering to stop people being paired with themselves. Or you could use "a < b" to make it return unordered unique pairings. \ No newline at end of file