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)
Related
when you add numbers in a list with foldr it works:
sumIntegers :: [Integer] -> Integer
sumIntegers xs = foldr (+) 0 xs
but to substract doesn't work the same way because
minus minus = plus. [2,3,4,5] is like: 2-3+4-5.
subtractNums' :: Num a => [a] -> a
subtractNums' xs = foldr (-) 0 xs
subtractNums :: Num a => [a] -> a
subtractNums [] = 0
subtractNums (x:xs) = x - subtractNums xs
What has to be changed?
thank you in advance
Addition is associative (and commutative, meaning it doesn't matter if the identity gets added first on the right, or last on the left), so both foldr and foldl compute the same sum:
foldr (+) 0 [1,2,3] == 1 + (2 + (3 + 0)) == 1 + 2 + 3 == 6
foldl (+) 0 [1,2,3] == ((0 + 1) + 2) + 3 == 1 + 2 + 3 == 6
However, subtraction is not associative; (x - y) - z does not, in general, equal x - (y - z), so foldr and foldl compute two different results:
foldl (-) 0 [1,2,3] == ((0 - 1) - 2) - 3
== (-1 - 2) - 3
== -3 - 3
== -6
foldr (-) 0 [1,2,3] == 1 - (2 - (3 - 0))
== 1 - (2 - 3)
== 1 - -1
== 2
Which function you choose depends on which running difference you actually want to compute.
bit array right to left, e.g. [0,1,0,1] = 10 can be read with:
binToInt = foldr (\x xs -> x + 2 * xs) 0
I would like to read it left to right, e.g. [1,0,1,0] = 10
I thought this would work:
binToInt' = foldr (\x xs -> (x * ((^) 2 (length xs)) + xs) 0
however I get the error:
Couldn't match type `t0 a0' with `Int'
what am I doing wrong?
(as a work around I am reversing the result of binToInt)
I solved my problem:
binToInt' = foldl (\acc x -> x + 2 * acc) 0
which unfolds to:
f = (\acc x -> x + 2 * acc)
foldl f 0
[1,0,1,0]
(f [1,0,1]) * 2 + 0
((f [1,0]) * 2 + 1) * 2 + 0
(((f [1]) * 2 + 0) * 2 + 1) * 2 + 0
((((f []) * 2 + 1) * 2 + 0) * 2 + 1) * 2 + 0
((((0) * 2 + 1) * 2 + 0) * 2 + 1) * 2 + 0
With the program below,
f 0 0 0 1 = 0
f 0 0 1 0 = f 0 0 0 1 + 1
f 0 1 0 0 = f 0 0 1 1 + 1
f 1 0 0 0 = f 0 1 1 1 + 1
f a b c d = (p + q + r + s) / (a + b + c + d)
where
p
| a > 0 = a * f (a - 1) (b + 1) (c + 1) (d + 1)
| otherwise = 0
q
| b > 0 = b * f a (b - 1) (c + 1) (d + 1)
| otherwise = 0
r
| c > 0 = c * f a b (c - 1) (d + 1)
| otherwise = 0
s
| d > 0 = d * f a b c (d - 1)
| otherwise = 0
main = print (f 1 1 1 1)
I thought it can be simplified as,
f 0 0 0 1 = 0
f 0 0 1 0 = f 0 0 0 1 + 1
f 0 1 0 0 = f 0 0 1 1 + 1
f 1 0 0 0 = f 0 1 1 1 + 1
f a b c d = (p + q + r + s) / (a + b + c + d)
where
p = a * f (a - 1) (b + 1) (c + 1) (d + 1)
q = b * f a (b - 1) (c + 1) (d + 1)
r = c * f a b (c - 1) (d + 1)
s = d * f a b c (d - 1)
main = print (f 1 1 1 1)
because besides both being mathematically sound, I thought that with lazy evaluation, the compiler or interpreter should be able to decide that multiplying anything to 0 is needless. But well, the program did go into infinite loop. Why so?
Built-in multiplication is strict in both arguments -- that is, it evaluates both arguments -- regardless of whether one of them is zero, which is what is causing your program to loop. You could define your own multiplication operator which lazily eliminates one or the other of the arguments:
0 .* y = 0
x .* y = x * y
or the other way around. It takes a bit more to define an operator which eliminates zero on both sides, but it can be done with the unamb package:
x .* y = unambs [ assuming (x == 0) 0
, assuming (y == 0) 0
, x * y
]
Though, as far as I know, this does not yet have a sufficiently reliable implementation :-/.
As well as defining your own multiplication operator as #luqui suggests, you can define your own type whose built-in multiplication short-circuits:
newtype SCZero a = SCZero a
deriving Eq
instance Show a => Show (SCZero a) where
show (SCZero x) = show x
instance (Eq a, Num a) => Num (SCZero a) where
SCZero x + SCZero y = SCZero (x + y)
SCZero 0 * SCZero y = SCZero 0
SCZero x * SCZero y = SCZero (x * y)
abs (SCZero x) = SCZero (abs x)
signum (SCZero x) = SCZero (signum x)
fromInteger x = SCZero (fromInteger x)
negate (SCZero x) = SCZero (negate x)
instance (Eq a, Fractional a) => Fractional (SCZero a) where
fromRational x = SCZero (fromRational x)
SCZero 0 / SCZero y = SCZero 0
SCZero x / SCZero y = SCZero (x / y)
You can then use your existing code directly, by just specifying the result type to be a SCZero:
*Main> print (f 1 1 1 1 :: SCZero Double)
0.464398781601087
How do I write
f 0 = 1
f x = (f(x-1))*2 + 2
as a lambda in Haskell?
Thanks in anticipation.
You'd move the pattern matching from the right and use a case expression
f = \ x -> case x of
0 -> 1
x -> f (x-1) * 2 + 1
f = \x -> if x == 0 then 1 else (f (x - 1)) * 2 + 2
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.