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