Rob's Wiki
  • Welcome
  • AWS
    • Appsync
    • Athena
    • S3
  • Terminal
    • brew
    • curl
    • git
    • kubernetes
    • ngrok
    • terminal
    • tmux
    • zsh
  • Design
    • Sketch
    • Fusion360
    • TinkerCAD
  • Haskell
    • Haskell
    • Stack, Cabal etc
  • Javascript
    • Javascript
    • npm
    • Vue
  • CSS
  • Mac
  • Python
    • iPython
    • pip
    • Virtualenv
  • Scala
  • Rust
  • VSCode
  • Keyboard Shortcuts
Powered by GitBook
On this page
  • GHCi
  • General syntax
  • Quick reference:
  • Guard syntax
  • 'where' clause
  • 'as' Pattern
  • Modules
  • Indentation
  • Types and Typeclasses
  • Record syntax declarations
  • newtype declarations
  • Typeclass: Semigroup
  • Typeclass: Monoids
  • Generalised Algebraic Datatypes (GADTs)
  • Miscellaneous
  • Template Haskell
  • Forall Keyword
  1. Haskell

Haskell

PreviousHaskellNextStack, Cabal etc

Last updated 6 years ago

GHCi

  • :reload reload all names in scope

  • :quit

  • :t 9 returns the type of 9

  • :info [] returns lots of useful details about the implemented typeclasses

  • :k Int returns the kind of Int

  • :set prompt "\x03BB > " would change the command prompt to λ >

  • :set -XExistentialQuantification sets up the language extension

You can give 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

describeLetter :: Char -> String
describeLetter c
   | c >= 'a' && c <= 'z' = "Lower case"
   | c >= 'A' && c <= 'Z' = "Upper case"
   | otherwise            = "Not an ASCII letter"

'where' clause

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 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

  • Import hiding

import Data.List hiding (nub)

Indentation

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

  • data means we're declaring a new type

  • Expr is the type constructor

  • I ..., Add ..., Mul ... are the value constructors

data Expr = I Int         -- integer constants
          | Add Expr Expr -- add two expressions
          | Mul Expr Expr -- multiply two expressions
data Expr = I Int         -- integer constants
          | Add Expr Expr -- add two expressions
          | Mul Expr Expr -- multiply two expressions
          deriving (Show)

Record syntax declarations

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

Typeclass: Semigroup

A set with an associative binary operation. Superset of Monoids.

Typeclass: Monoids

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 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

{-# LANGUAGE TemplateHaskell #-}

It is used e.g. by lens to generate the various lenses into data structures at compile time

Forall Keyword

allows us to conditionally check a statement within a pattern matching expression.

Define inline bindings (e.g. to functions or values). The uses guards and a where clase:

The 'as' pattern (described , and ), gives us a way of matching a name for the entire element being pattern matched in a list:

from 'Learn you a Haskell' is a good reference.

From , the golden rule of indentation is:

In the following snippet ():

Adding deriving (Show) at the end of a data declaration automatically makes that type part of the Show typeclass ():

providing data accessors:

For the moment, I treat newtype as being broadly interchangable with data when creating a new type. There's documentation about it .

is a typeclass with an associative mappend operation and an identity element.

The crux of is that the provide a way to explicitly declare the type signature of each constructor.

is similar to Lisp macros.

forall when defining new data types

multiline input
Guard Syntax
following example
here
here
here
This page
this page
reference
reference
Syntactic sugar
here
Monoid
GADTs
Template Haskell
imposes constraints on parameterising types