mirror of
https://github.com/thma/WhyHaskellMatters.git
synced 2024-09-11 13:46:11 +03:00
work on higher order example
This commit is contained in:
parent
8c6019bc8e
commit
7c2b4e34c4
74
README.md
74
README.md
@ -96,7 +96,7 @@ I'll try to keep the learning curve moderate and so I'll start with some very ba
|
||||
Even though I'll try to keep the presentation self-contained it's not intended to be an introduction to the Haskell language
|
||||
(have a look at [Learn You a Haskell](http://www.learnyouahaskell.com/) if you are looking for enjoyable tutorial).
|
||||
|
||||
## First-class Functions
|
||||
## Functions are First-class
|
||||
|
||||
> In computer science, a programming language is said to have first-class functions if it treats functions as
|
||||
> first-class citizens. This means the language supports **passing functions as arguments to other functions**,
|
||||
@ -138,15 +138,74 @@ The only thing special is that we declare the type to be a **function type** by
|
||||
So `:: Integer -> Integer` represents a function from `Integer` to `Integer`.
|
||||
In the second line we define function `square` to compute `x * x` for any `Integer` argument `x`.
|
||||
|
||||
Ok, seems not too difficult, let's define a function `double` that doubles its input value:
|
||||
Ok, seems not too difficult, so let's define another function `double` that doubles its input value:
|
||||
|
||||
```haskell
|
||||
double :: Integer -> Integer
|
||||
double n = 2 * n
|
||||
```
|
||||
|
||||
### support for anonymous functions
|
||||
|
||||
Anonymous functions, also known as lambda expressions, can be defined in Haskell like this:
|
||||
|
||||
```Haskell
|
||||
\x -> x * x
|
||||
```
|
||||
|
||||
This expression denotes an anonymous function that takes a single argument x and returns the square of that argument.
|
||||
The backslash is read as λ (the greek letter lambda).
|
||||
|
||||
You can use such as expressions everywhere where you would use any other function. For example you could apply the
|
||||
anonymous function `\x -> x * x` to a number just like the named function `square`:
|
||||
|
||||
```haskell
|
||||
-- use named function:
|
||||
result = square 5
|
||||
|
||||
-- use anonymous function:
|
||||
result' = (\x -> x * x) 5
|
||||
```
|
||||
|
||||
We will see more useful applications of anonymous functions in the following section.
|
||||
|
||||
### Functions can be returned as values from other functions
|
||||
|
||||
#### function composition
|
||||
|
||||
Do you remember *function composition* from your high-school math classes?
|
||||
Function composition is an operation that takes two functions `f` and `g` and produces a function `h` such that
|
||||
`h(x) = g(f(x))`
|
||||
The resulting composite function is denoted `h = g ∘ f` where `(g ∘ f )(x) = g(f(x))`.
|
||||
Intuitively, composing functions is a chaining process in which the output of function `f` is used as input of function `g`.
|
||||
|
||||
So looking from a programmers perspective the `∘` operator is a function that
|
||||
takes two functions as arguments and returns a new composite function.
|
||||
|
||||
In Haskell this operator is represented as the dot operator `.`:
|
||||
|
||||
```haskell
|
||||
(.) :: (b -> c) -> (a -> b) -> a -> c
|
||||
(.) f g = \x -> f (g x)
|
||||
```
|
||||
|
||||
The brackets around the dot are required as we want to use a non-alphabetical symbol as an identifier.
|
||||
In Haskell such identifiers can be used as infix operators (as we will see below).
|
||||
Otherwise `(.)` is defined as any other function.
|
||||
|
||||
Using this operator we can easily create a composite function that first doubles a number and then computes the square
|
||||
of the doubled number:
|
||||
|
||||
```haskell
|
||||
-- combining functions with the `.` operator: (.) :: (b -> c) -> (a -> b) -> a -> c
|
||||
squareAfterDouble :: Integer -> Integer
|
||||
squareAfterDouble = square . double
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Currying and Partial Application
|
||||
|
||||
We define a function `add`that takes two `Integer` arguments and computes their sum:
|
||||
|
||||
```haskell
|
||||
@ -192,15 +251,12 @@ This technique is frequently used to provide functions with configuration data.
|
||||
|
||||
### Functions can be passed as arguments to other functions
|
||||
|
||||
### It's possible to define anonymous functions
|
||||
|
||||
Anonymous functions can be defined like this:
|
||||
```Haskell
|
||||
-- define a function `square` which takes an Integer as argument and compute its square
|
||||
square :: Integer -> Integer
|
||||
square = \x -> x * x
|
||||
```
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
This is my scrap book (don't look at it)
|
||||
|
||||
- Funktionen sind 1st class citizens (higher order functions, Funktionen könen neue Funktionen erzeugen und andere Funktionen als Argumente haben)
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
module Functions where
|
||||
|
||||
import Data.Natural
|
||||
import Control.Arrow ((>>>))
|
||||
import Data.Natural
|
||||
import Prelude hiding ((.))
|
||||
|
||||
-- define constant `aNumber` with a value of 42.
|
||||
-- define constant `aNumber` with a value of 42.
|
||||
aNumber :: Integer
|
||||
aNumber = 42
|
||||
|
||||
@ -18,6 +19,11 @@ square n = n ^ 2
|
||||
double :: Integer -> Integer
|
||||
double n = 2 * n
|
||||
|
||||
-- combining functions with the `.` operator: (.) :: (b -> c) -> (a -> b) -> a -> c
|
||||
squareAfterDouble :: Integer -> Integer
|
||||
--squareAfterDouble = square . double
|
||||
squareAfterDouble n = (square . double) n
|
||||
|
||||
ifOddDouble :: Integer -> Integer
|
||||
ifOddDouble n =
|
||||
if odd n
|
||||
@ -29,7 +35,7 @@ ifOddSquare n =
|
||||
if odd n
|
||||
then square n
|
||||
else n
|
||||
|
||||
|
||||
ifOdd :: (Integer -> Integer) -> Integer -> Integer
|
||||
ifOdd growthFunction n =
|
||||
if odd n
|
||||
@ -39,9 +45,8 @@ ifOdd growthFunction n =
|
||||
ifOddSquare' :: Integer -> Integer
|
||||
ifOddSquare' n = ifOdd square n
|
||||
|
||||
|
||||
ifPredGrow :: (Integer -> Bool) -> (Integer -> Integer) -> Integer -> Integer
|
||||
ifPredGrow predicate growthFunction n =
|
||||
ifPredGrow predicate growthFunction n =
|
||||
if predicate n
|
||||
then growthFunction n
|
||||
else n
|
||||
@ -52,13 +57,11 @@ ifOddDouble' n = ifPredGrow odd double n
|
||||
ifEvenSquare' :: Integer -> Integer
|
||||
ifEvenSquare' n = ifPredGrow even square n
|
||||
|
||||
|
||||
|
||||
-- function taking a tuple of two Integers and computing their product
|
||||
mul :: (Integer, Integer) -> Integer
|
||||
mul (x, y) = x * y
|
||||
|
||||
-- function adding two numbers
|
||||
-- function adding two numbers
|
||||
add :: Integer -> Integer -> Integer
|
||||
add x y = x + y
|
||||
|
||||
@ -66,6 +69,9 @@ add x y = x + y
|
||||
add5 :: Integer -> Integer
|
||||
add5 = add 5
|
||||
|
||||
(.) :: (b -> c) -> (a -> b) -> a -> c
|
||||
(.) f g x = f (g x)
|
||||
|
||||
-- combining functions with the `.` operator: (.) :: (b -> c) -> (a -> b) -> a -> c
|
||||
add5AndSquare :: Integer -> Integer
|
||||
add5AndSquare = square . add5
|
||||
@ -83,9 +89,9 @@ curMul = curry mul
|
||||
uncurAdd :: (Integer, Integer) -> Integer
|
||||
uncurAdd = uncurry add
|
||||
|
||||
-- recursive definition of factorial
|
||||
-- recursive definition of factorial
|
||||
factorial :: Natural -> Natural
|
||||
factorial n =
|
||||
factorial n =
|
||||
if n == 0
|
||||
then 1
|
||||
else n * factorial (n - 1)
|
||||
@ -94,6 +100,3 @@ factorial n =
|
||||
fac :: Natural -> Natural
|
||||
fac 0 = 1
|
||||
fac n = n * fac (n - 1)
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user