Haskell
GHCi
:reloadreload all names in scope:quit:t 9returns the type of9:info []returns lots of useful details about the implemented typeclasses:k Intreturns the kind ofInt:set prompt "\x03BB > "would change the command prompt toλ >:set -XExistentialQuantificationsets 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):
datameans we're declaring a new typeExpris 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 expressionsAdding
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 aMiscellaneous
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