Haskell

OK, this page is indeed beginner friendly because I'm also pretty new to Haskell.
But I guess by beginner I mean beginner to functional programming, NOT beginner to programming as a whole.

Environment Related

Steps to step to set up the env on a Mac with Intel chip: follow this guide
Several ways to compile and run: document tree of stack

Principles

Basis

Lists

lists in haskell are singular linked lists. Only elements of the same data type are allowed to be in the same list.
But this is allowed because it's a list of lists: [[1,2],[8,11,5],[4,5]]

Tuples

Tuples are not homogenous, meaning they can contain multiple data types.

Types

Haskell is statically typed, meaning that the type of every expression is known at compile time.
Haskell uses type inference, so you don't have to explicitly specify the type of every expression.

For functions, the return value is the last type in its type declaration.

Type annotation: read "5" :: Int
Specify the type of an expression explicitly by adding :: after it.

Type variables:
head :: [a] -> a
The a here is a type variable, meaning it can be of any type. Similarly there can be b etc.
Within the same type signature, if you use the same type variable, it means that the two types are the same.
Functions that have type variables are called polymorphic functions.

Type classes:
Type classes are like interfaces in Java.
(==) :: (Eq a) => a -> a -> Bool
Everything before => is called a class constraint. You can regard it as some constraint imposed on the type variable a. In our case, the type constraint specifies that a must be a type that belongs to the Eq type class, which is essentially an interface to test for equality.
Everything after => can be intepreted the same way as you did for function.
Some basic type classes:
User-defined Types
data Bool = False | True

Modules

Haskell modules; User-defined modules:
-- in Geometry.hs
module Geometry
( sphereVolume
, sphereArea
, squareArea
, squareVolume) where
-- define the functions here


-- in Sphere.hs
module Geometry.Sphere
( volume
, area) where
-- define the functions here

Functions

Function data type: with multiple arguments, functions are actually function that returns functions that returns functions...each of these functions is a single argument function

Call a function

Define a function

Guards

bmiTell :: (RealFloat a) => a -> String 
bmiTell bmi | bmi <= 18.5 = "Underweight"
| bmi <= 25.0 = "Normal"
| otherwise = "Overweight"

Recursion

factorial :: (Eq a, Num a) => a -> a
factorial 0 = 1 
factorial n = n * factorial (n - 1)

Higher order functions

Higher order function refers to the fact that functions can be used as parameters and return values.
Example that function can be used as a return value:
max :: (Ord a) => a -> a -> a 
-- essentially the same as 
max :: (Ord a) => a -> (a -> a)
Two ways to interpret this:
1. max takes two parameters and returns a value of the same type
2. max takes one parameter and returns a function that takes one parameter and returns a value of the same type -> function application happens to the closest argument

Example that function can be used as a parameter:
applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)
Notice the type declaration: (a -> a) is the type of a function. The parenthesis cannot be omitted because -> is right associative.

Some standard prelude functions commonly used