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