Haskell
GHCi
:reload
reload all names in scope:quit
:t 9
returns the type of9
:info []
returns lots of useful details about the implemented typeclasses:k Int
returns the kind ofInt
:set prompt "\x03BB > "
would change the command prompt toλ >
:set -XExistentialQuantification
sets up the language extension
You can give multiline input to GHCi as follows:
*Main> :{
*Main| let askname = do
*Main| putStrLn "What is your name?"
*Main| name <- getLine
*Main| putStrLn $ "Hello " ++ name
*Main| :}
*Main>
General syntax
Quick reference:
The best way to find out about these kind of constructs in ghci, e.g. :info <*>
:
(.)
- Function composition<*>
$
Guard syntax
Guard Syntax allows us to conditionally check a statement within a pattern matching expression.
describeLetter :: Char -> String
describeLetter c
| c >= 'a' && c <= 'z' = "Lower case"
| c >= 'A' && c <= 'Z' = "Upper case"
| otherwise = "Not an ASCII letter"
'where' clause
Define inline bindings (e.g. to functions or values). The following example uses guards and a where clase:
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell weight height
| bmi <= 18.5 = "You're underweight, you emo, you!"
| bmi <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"
| bmi <= 30.0 = "You're fat! Lose some weight, fatty!"
| otherwise = "You're a whale, congratulations!"
where bmi = weight / height ^ 2
'as' Pattern
The 'as' pattern (described here, here and here), gives us a way of matching a name for the entire element being pattern matched in a list:
The following would be read all as (x:xs)
:
capital :: String -> String
capital "" = "Empty string, whoops!"
capital all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x]
Modules
This page from 'Learn you a Haskell' is a good reference.
Import hiding
import Data.List hiding (nub)
Indentation
From this page, the golden rule of indentation is:
Code which is part of some expression should be indented further in than the beginning of that expression...All grouped expressions must be exactly aligned
But you can avoid indentation:
Indentation is actually optional if you instead use semicolons and curly braces
Types and Typeclasses
In the following snippet (reference):
data
means we're declaring a new typeExpr
is the type constructorI ...
,Add ...
,Mul ...
are the value constructors
data Expr = I Int -- integer constants
| Add Expr Expr -- add two expressions
| Mul Expr Expr -- multiply two expressions
Adding
deriving (Show)
at the end of a data declaration automatically makes that type part of the Show typeclass (reference):
data Expr = I Int -- integer constants
| Add Expr Expr -- add two expressions
| Mul Expr Expr -- multiply two expressions
deriving (Show)
Record syntax declarations
Syntactic sugar providing data accessors:
data Configuration = Configuration
{ username :: String
, localHost :: String
, remoteHost :: String
, isGuest :: Bool
, isSuperuser :: Bool
, currentDir :: String
, homeDir :: String
, timeConnected :: Integer
}
You can pattern match against them:
getHostData (Configuration { localHost = lh, remoteHost = rh }) = (lh, rh)
And create new versions with certain fields overwritten using:
cfg { currentDir = newDir }
newtype
declarations
newtype
declarationsFor the moment, I treat newtype
as being broadly interchangable with data
when creating a new type. There's documentation about it here.
Typeclass: Semigroup
A set with an associative binary operation. Superset of Monoids.
Typeclass: Monoids
Monoid is a typeclass with an associative mappend
operation and an identity element.
Integer numbers form a monoid under addition with 0 as identity element Integer numbers form a monoid under multiplication with 1 as identity element Lists form a monoid under concatenation with the empty list as identity element
mappend
is given the infix synonym (<>)
Generalised Algebraic Datatypes (GADTs)
The crux of GADTs is that the provide a way to explicitly declare the type signature of each constructor.
The following language option is required:
{-#LANGUAGE GADTs #-}
And then an example would be:
data Maybe a where
Nothing :: Maybe a
Just :: a -> Maybe a
Miscellaneous
Template Haskell
Template Haskell is similar to Lisp macros.
{-# LANGUAGE TemplateHaskell #-}
It is used e.g. by lens
to generate the various lenses into data structures at compile time
Forall Keyword
forall
imposes constraints on parameterising types when defining new data types
Last updated