Haskell

From bibbleWiki
Jump to navigation Jump to search

Introduction

This is my first dip into Haskell, just felt like trying it. Haskell is a purely functional programming language. rather than a declarative language. I.E. it is a declarative language rather than imperative. With declarative, you tell the language what the thing is rather than how to do the thing.

Features

Lazy

Haskell is a programming lazy language and only evaluates on usage. E.g. only evaluates the first 10

let infiniteList =  [1..]
take 10 infiniteList

Modules

Starting to look a lot like Lisp. This next bit shows how you can combine various functions of your own to produce and output

let double = x = x * 2
let increment x = x + 1
let doubleThenIncrement x = increment(double x)
doubleThenIncrement 10 -- Answer is 21

Statically Typed

With Haskell types are inferred

Hello World

Here we start with main and strange format but no curly brackets which is good.

main :: IO()
main = putStrLn "Hello World"

We build like gcc using

ghc hello.hs -o hello

Date Models

Types

  • Numbers e.g. 1
  • Chars e.g. "S"
  • Boolean e.g. True, False
  • List e.g. [1,2,3], [True, False, True]
  • Tuple e.g. (1,2,3, "string, True)

List Comprehension

You can define a function and operate against a list like this

[x*2 | x <-[1..10]] -- Answer is [2,4,6,8,10,12,14,16,18,20]

Constructs

Pattern Matching

No surprises, and I love pattern matching

-- Pattern Matching
coffeeType :: String -> String
coffeeType "Epresso" = "Strong and bold"
coffeeType "Cappuccino" = "Frothy and delicious"
coffeeType "Filter" = "Watery and weak"
coffeeType _ = "I have no idea what that is"

main = do 
    print(coffeeType "Epresso")
    print(coffeeType "Cappuccino")
    print(coffeeType "Filter")
    print(coffeeType "Latte")

Guards

Again no surprise here

bookCategory :: Int -> String
bookCategory age
    | age < 10 = "Children's book"
    | age < 18 = "Teen book"
    | otherwise = "Adult book"

main = do
    print(bookCategory 5)
    print(bookCategory 15)
    print(bookCategory 25)

Where Clause

Almost writes its self

populationDensity :: (Double, Float) -> String

populationDensity (population, area) = density where density = population / area

main = do
    print(populationDensity (100000, 1000))

Recursion

Where would we be without Factorial

-- Factorial
factorial :: Int -> Int
-- Base case
factorial 0 = 1
-- Recursive case
factorial n = n * factorial (n - 1)

main = do
    print(factorial 5)

Higher Order Functions

Higher order functions are functions that take one or more functions as arguments, or return a function as their result. In the example we had our friends from Typescript, map and filter,

let increment x = x + 1
map increment [1,2,3] -- [2,3,4]

And filter, loving the mod operation

let isEven n = n `mod` 2 == 0
filter isEven [2,3,4] -- [2,4]

Finally something new, foldl, i.e. apply operation start from position using array from left to right (lispy)

foldl (+) 0 [1,2,3,4,5] -- 15

And now first use of libraries

import Data.List (sort)
sort [10, 2, 5, 3, 6, 7, 4, 8, 9, 1]

Other functions were zipWith, takeWhile, dropWhile

-- All
all even [1,2,4] -- False
any even [1,2,4] -- True

Lambda Expressions

This is a shortcut to writing unnamed function. We do this by specifying a back slash. e.g.

print((\c -> c * 9/5 + 32) 25) -- 77.0

More On Functions

Other Built-in Functions

We have head,tail, last, init

let x = [1..10]
head x -- 1
tail x -- [2,3,4,5,6,7,8,9,10]
last x -- 10
init x -- [1,2,3,4,5,6,7,8,9]
reverse x -- [10,9,8,7,6,5,4,3,2,1]
length x -- 10
take 5 (x) -- [1,2,3,4,5]
drop 6 (x) -- [7,8,9,10] 
sum x -- 55
product x -- 3628800
elem 8(x) -- True Searches list

Function Composition

Here we can combine functions in one call. This just looks like chaining to me but here is the example like in Maths when you have f{g(x)}

-- IsEven function
isEven :: Int -> Bool
-- Is Odd function
isNotEven :: Bool -> String

isEven x = if x `rem` 2 == 0 
then True
else False

isNotEven x = if x == True
  then "This is an Even Number"
else "This is an Odd Number"

main = do
    print((isNotEven.isEven) 5)