Haskell: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 131: Line 131:
print((\c -> c * 9/5 + 32) 25) -- 77.0
print((\c -> c * 9/5 + 32) 25) -- 77.0
</syntaxhighlight>
</syntaxhighlight>
=More On Functions==
=More On Functions=
==Other Built-in Functions==
==Other Built-in Functions==
We have head,tail, last, init
We have head,tail, last, init

Revision as of 23:36, 10 February 2025

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

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