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
Related
I wrote this binarytodecimal-converter getting a compiler error I don't know where it's comming from.
binaryToInteger :: [Bool] -> Integer
binaryToInteger (x:xs) = foldr (\x y z -> (fromEnum x) * 2^y + z) 0 [0..length (x:xs)]
Actually the program should give back the decimal result of a binary number.
Example given:
binaryToInteger [True, True, False] == 1(2^2) + 1*(2^1) + 0*(2^0) == 6*
My error message is the following:
Couldn't match expected type Integer' with actual typeInt -> Int'
* Probable cause: `foldr' is applied to too few arguments
In the expression:
foldr (\ x y z -> (fromEnum x) * 2 ^ y + z) 0 [0 .. length (x : xs)]
In an equation for `binaryToInteger':
binaryToInteger (x : xs)
= foldr
(\ x y z -> (fromEnum x) * 2 ^ y + z) 0 [0 .. length (x : xs)]
The algorithm goes like this:
you start with a = 0 ("a" stands for "accumulator")
for True: double a and add 1 to it
for False: just double a
Example: [True, False, True]
a = 0
True => a becomes 1 (because 0 * 2 + 1 = 1)
False => a becomes 2 (because 1 * 2 = 2)
True => a becomes 5 (because 2 * 2 + 1 = 5)
a = 5 is the solution
In Haskell code:
import Data.List (foldl')
binaryToInteger :: [Bool] -> Integer
binaryToInteger xs = foldl' f 0 xs where
f a True = a * 2 + 1
f a False = a * 2
Don't use exponentiation (^), because it is bad for performance. I used a left-fold, because it is better suited for this problem. The function foldl' has the additional advantage that it is strict, and therefore doesn't introduce a space leak.
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.
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)
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
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.