parallelism in haskell integration function [on hold] - haskell

How to correctly introduce parallelism on simpson functions?
simpsonIntegrate f a b n =
parMap rseq( (s + s4 + s2) * h / 6)
where
s = f a + f b
s4 = 4 * (sum . map f $ [a + h/2, a + h/2 + h .. b - h/2])
s2 = 2 * (sum . map f $ [a + h, a + 2*h .. b - h])
h = (b - a) / n

Related

Determining the mathematical operations which were executed in a function in Haskell

Question
I encountered the following code-snippet:
fun a b c d = let y = a * b
f x = (x + y) `div` y
in f c + f d
An example output for fun 5 6 7 8 would be 2.5.
Unfortunately, I couldn't reproduce for myself for at least some minutes, which mathematical operations are being executed. As I wrote this question, I figured out the solution: (I know it's really trivial, but I wanted to share my problems with you guys, in case someone has a similar problem.)
Solution
It's obvious that y = 5 * 6 = 30 and f x = (x + y) / y
is a pattern for f c + f d namely f c = ((c + y) / y) + f d = ((d + y) / y)
That's why by using substitution we obtain:
fun 5 6 7 8 = let y = a * b -- 5 * 6 = 30
f x = ((x + y) / y) -- Pattern
in f c + f d -- ((7 + 30) / 30) + ((8 + 30) / 30) ≈ 2.5

How do I implement nested functions in haskell

I recently came across this question:
Which basically asks how to implement this function to calculate the limit of f(n):
How would I implement this in haskell? I am trying to learn functional programming and this seems a good challenge for me now
There's a bunch of ways!
Here's one using a recursive helper function:
f :: (Eq a, Floating a) => a -> a
f n = f' n n
where f' 1 x = x
f' n x = let n' = n-1 in f' n' (n' / (1 + x))
Working it out by hand:
f 1 = f' 1 1
= 1
f 2 = f' 2 2
= f' 1 (1 / (1 + 2))
= 1/(1+2)
f 3 = f' 3 3
= f' 2 (2 / (1 + 3))
= f' 1 (1 / (1 + (2 / (1 + 3))))
= 1 / (1 + (2 / (1 + 3)))
Here's a different way to do it with a recursive helper function:
f :: (Eq a, Floating a) => a -> a
f n = f' 1 n
where f' a n | a == n = a
| otherwise = a / (1 + f' (a+1) n)
Working it out by hand:
f 1 = f' 1 1
= 1
f 2 = f' 1 2
= 1 / (1 + f' 2 2)
= 1 / (1 + 2)
f 3 = f' 1 3
= 1 / (1 + f' 2 3)
= 1 / (1 + (2 / (1 + f' 3 3)))
= 1 / (1 + (2 / (1 + 3)))
The first approach was tail-recursive while the second was simply recursive.
Or, as the link says, by a fold
f :: (Eq a, Floating a) => a -> a
f n = foldr1 (\n x -> n / (1 + x)) [1..n]
Again, working it out by hand:
f 5 = foldr1 (\n x -> n / (1 + x)) [1,2,3,4,5]
= g 1 (g 2 (g 3 (g 4 5)))
= g 1 (g 2 (g 3 (4 / (1 + 5))))
= g 1 (g 2 (3 / (1 + (4 / (1 + 5)))))
= g 1 (2 / ( 1 + (3 / (1 + (4 / (1 + 5))))))
= 1 / (1 + (2 / ( 1 + (3 / (1 + (4 / (1 + 5)))))))
where g = \n x -> n / (1 + x)

Haskell: where clause referencing bound variables in lambda

I am trying to numerically integrate a function in Haskell using the trapezoidal rule, returning an anti-derivative which takes arguments a, b, for the endpoints of the interval to be integrated.
integrate :: (Float -> Float) -> (Float -> Float -> Float)
integrate f
= \ a b -> d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
where
d = (b - a) / n
n = 1000
In the above, I use
n - for the number of subintervals
d - for the width of each subinterval
This almost works, except for the bound arguments a,b in the lambda. I get the
error message:
Not in scope: `b'
Not in scope: `a'
I can understand that the scope of a,b is restricted to just that lambda expression, but
is there a workaround in Haskell so that I don't have to write (b-a)/n for each occurrence of d in the above?
You're thinking you need to return a function which takes two Floats and returns a Float, but actually that's no different to taking two extra Float arguments in your integrate function and using currying (i.e. just don't provide them and the return type will be Float -> Float -> Float).
So you can rewrite your function like this
integrate :: (Float -> Float) -> Float -> Float -> Float
integrate f a b
= d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
where
d = (b - a) / n
n = 1000
Or you could use let ... in instead of where:
integrate f
= \a b ->
let d = (b - a / n)
n = 1000
in d * sum [ f (a + d * k) | k <- [0..n] ] - d/2.0 * (f a + f b)
Sure.
integrate f a b = d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
where
d = (b - a) / n
n = 1000
You have a lot of work-arounds.
If you don't know any binding syntax except lambda expressions you can do this (which I love the most because of its theoretical beauty, but never use because of its syntactic ugliness):
integrate f
= \a b -> (\d -> d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b))
((b - a) / n)
where
n = 1000
If you like definitions and only know where-syntax you can do this:
integrate f = go
where
n = 1000
go a b = d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
where
d = (b - a) / n
If you also know let-syntax, you can do this:
integrate f =
\a b -> let d = (b - a) / n
in d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
where
n = 1000
Finally, if you remember that a -> (b -> c -> d) is the same as a -> b -> c -> d, you can do the obvious:
integrate f a b = d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
where
n = 1000
d = (b - a) / n
If you insist on where:
integrate f = \a b -> case () of
() -> d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
where
d = (b - a) / n
n = 1000
Looks pretty nice, does it not?
To make the case look a bit more motivated:
integrate f = \a b -> case (f a + f b) of
fs -> d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * fs
where
d = (b - a) / n
n = 1000
try:
integrate f a b = d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
where
d = (b - a) / n
n = 1000

Reusing a Lambda function in Haskell

I'm supposed to take this code:
f x y z = x^3 - g (x + g (y - g z) + g (z^2))
where g x = 2*x^2 + 10*x + 1
And rewrite it without where (or let).
They mean to write it with a Lambda function (\x ->...)
I'm trying to reuse a Lambda function on Haskell. Any ideas?
As bravit hints at, you can rewrite a non-recursive let using a lambda in the following way:
let x = A in B ==> (\x -> B) A
where x is a variable and A and B are expressions.
To reuse something you can make it an argument to something.
I think the intention is what bravit hints at.
The smartypants follow-the-letters-of-the-law workaround is binding g with a case ;)
To expand on hammar's and bravit's hints, your solution is going to require not just one lambda, but two - one of which will look a great deal like g, and the other of which will look a great deal like the second half of f
Using lambda calculus g is (\x -> 2*x^2 + 10*x + 1)
So you need to substitute g with that in f x y z = x^3 - g (x + g (y - g z) + g (z^2))
$> echo "f x y z = x^3 - g (x + g (y - g z) + g (z^2))" | sed -r -e 's/g/(\\x -> 2*x^2 + 10*x + 1)/g'
f x y z = x^3 - (\x -> 2*x^2 + 10*x + 1) (x + (\x -> 2*x^2 + 10*x + 1) (y - (\x -> 2*x^2 + 10*x + 1) z) + (\x -> 2*x^2 + 10*x + 1) (z^2))
I'm just kidding, sorry.
That question seems kinda curious and interesting for me. So, I'm trying to figured out what is lambda calculus is, find an answer and want to show it to OP (all hints have already been showed actually, spoiler alert).
Firstly, lets try to redefine f:
λ> let f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2)))
f ::
(Integer -> Integer) -> Integer -> Integer -> Integer -> Integer
So, we've got function, which get function and 3 numbers and return the answer. Using curring we can add g definition right here, like f_new = f g:
λ> let f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2))) (\x -> 2*x^2 + 10*x + 1)
f :: Integer -> Integer -> Integer -> Integer
We're done. Let's check it:
λ> f 0 0 0
-13
The answer is correct.
UPD:
In those examples let is just a way to declare function in the interpreter, so final answer is:
f :: Num a => a -> a -> a -> a
f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2))) (\x -> 2*x^2 + 10*x + 1)

Calculation steps in Haskell foldr

Does anybody know the steps of haskell 'foldr' use of function?
GHCI Command Window:
foldr (\x y -> 2*x + y) 4 [5,6,7]
The result after evaluation:
40
Steps on this,
Prelude> foldr (\x y -> 2*x + y) 4 [5,6,7]
6 * 2 + (7 * 2 + 4)
12 + 18 = 30
5 * 2 + 30 = 40 v
One definition of foldr is:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f acc [] = acc
foldr f acc (x:xs) = f x (foldr f acc xs)
The wikibook on Haskell has a nice graph on foldr (and on other folds, too):
: f
/ \ / \
a : foldr f acc a f
/ \ -------------> / \
b : b f
/ \ / \
c [] c acc
I.e. a : b : c : [] (which is just [a, b, c]) becomes f a (f b (f c acc)) (again, taken from wikibook).
So your example is evaluated as let f = (\x y -> 2*x + y) in f 5 (f 6 (f 7 4)) (let-binding only for brevity).
You can actually easily visualize it for yourself:
import Text.Printf
showOp f = f (printf "(%s op %s)") "0" ["1","2","3"]
then
Main> showOp foldr
"(1 op (2 op (3 op 0)))"
Main> showOp foldl
"(((0 op 1) op 2) op 3)"
Main> showOp scanl
["0","(0 op 1)","((0 op 1) op 2)","(((0 op 1) op 2) op 3)"]
[This was supposed to be a comment on delnan's remark, but was too wordy...]
Yoon, you can open a private 'conversation' with lambdabot on the #haskell irc (e.g. at http://webchat.freenode.net/ ). She has a simple reflection ability, so you can type meaningless letters, e.g.
Yoon: > foldr (\x y -> 2*x + y) o [a,b,c,d]
lamdabot: 2 * a + (2 * b + (2 * c + (2 * d + o)))
This says what is evaluated, but as Edka points out you get a picture of the order of evaluation from say
Yoon: > reverse (scanr (\x y -> 2*x + y) o [a,b,c,d])
lambdabot: [o,2 * d + o,2 * c + (2 * d + o),2 * b + (2 * c + (2 * d + o)),2 * a + (2 * b + (2 * c + (2 * d + o)))
I remember imprinting some good lessons playing around with foldr, foldl, scanr, scanl and this clever device.

Resources