If I have this Haskell function:
Consider the following Haskell function f :
f :: Int -> Int
f 0 = 1
f x = x * x * f (x - 1)
Then how can I calculate its fixpoint and the least fixpoint (in closed form)?
The answer to this question is :
How is this least fixpoint calculated? I am trying to understand this, but still no luck. It will be great if someone could explain this to me.
It is easy to see that
f x = x * x * f (x-1)
= x * x * ((x-1) * (x-1) * f (x-2))
= x * x * ((x-1) * (x-1) * ((x-2) * (x-2) * f (x-3)))
= ...
= x * x * ((x-1) * (x-1) * ((x-2) * (x-2) * ... * 1)))
Now to answer your question in the comments about how this is equivalent to the given formula (x!)^2 when the recursive result f (x-1) is not squared, just rearrange the factors above, using associativity and commutativity of (*) over Int :
x * x * ((x-1) * (x-1) * ((x-2) * (x-2) * ... * 1)))
= x * x * (x-1) * (x-1) * (x-2) * (x-2) * ... * 1
= (x * (x-1) * (x-2) * ... * 1) * (x * (x-1) * (x-2) * .. * 1)
= x! * x!
= (x!)^2
Related
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
I'm really new to Haskell, and it's giving me quite a time. I was trying to write a basic function similar to 'linspace' in Matlab but the compiler seems to reject the idea that 'floor' produces an Integral type. My code:
linspace :: Double -> Double -> Double -> [Double]
linspace x dx y
| y' == y = [x + i * dx | i <- nums]
| otherwise = ([x + i * dx | i <- nums] ++ [y])
where
n = floor ((y - x) / dx)
nums = [0..n]
y' = (x + (fromIntegral n) * dx)
Which produces an error in ghci:
maths.hs:8:21: error:
* No instance for (Integral Double) arising from a use of `floor'
* In the expression: floor ((y - x) / dx)
In an equation for `n': n = floor ((y - x) / dx)
In an equation for `linspace':
linspace x dx y
| y' == y = [x + i * dx | i <- nums]
| otherwise = ([x + i * dx | i <- nums] ++ [y])
where
n = floor ((y - x) / dx)
nums = [0 .. n]
y' = (x + (fromIntegral n) * dx)
maths.hs:10:28: error:
* No instance for (Integral Double)
arising from a use of `fromIntegral'
* In the first argument of `(*)', namely `(fromIntegral n)'
In the second argument of `(+)', namely `(fromIntegral n) * dx'
In the expression: (x + (fromIntegral n) * dx)
Failed, modules loaded: none.
You have bound the result of linspace to be a [Double], due to the type annotation. Therefore, [x + i * dx | i <- nums] must produce such a list of Doubles. x and dx are bound to be Double as they are parameters passed to the function, which are all declared as Double. But what about i? It stems from nums; to have i be a Double, nums must be a [Double].
Nums is defined as
nums = [0..n]
Okay, nums is a list alright. But a list of what? That depends on n; let's take a look!
n = floor ((y - x) / dx)
floor takes, in a nutshell, your Double and produces an Integral. Therefore, nums is a list of integrals. This is the error you're getting: there is no instance of Integral for Double; there is no way for the types to work out nicely.
To fix those errors, you have to make n a Double:
n = fromIntegral $ floor ((y - x) / dx)
As such, your definition of y' must be changed as well:
y' = x + n * dx
In a nutshell
linspace :: Double -> Double -> Double -> [Double]
linspace x dx y
| y' == y = [x + i * dx | i <- nums]
| otherwise = ([x + i * dx | i <- nums] ++ [y])
where
n = fromIntegral $ floor ((y - x) / dx)
nums = [0.. n]
y' = (x + n * dx)
This version compiles:
linspace :: Double -> Double -> Double -> [Double]
linspace x dx y
| y' == y = [x + (fromIntegral i) * dx | i <- nums]
| otherwise = ([x + (fromIntegral i) * dx | i <- nums] ++ [y])
where
n = toInteger $ floor ((y - x) / dx)
nums = [0..n]
y' = (x + (fromIntegral n) * dx)
What are the changes?
As #Alec commented, while floor is logically an integer, it's type is not. You need to use toInteger.
Following that, you need to use fromIntegral when multiplying i and `dex.
Let's see analyse code for factorial in Haskell using lambda function:
y f x = f (y f) x
factorial = y (\t n -> if n == 1 then 1 else n * t(n-1))
And I cannot understand how does it works. I know that it is connected with lambda calculus but nowadays I am not familiar with that so I have to understand without it or with minimal knowledge.
My doubt is:
What is f in definition of factorial? I mean this f: y f x = f (y f) x.
So what is f here? y (\t n -> if n == 1 then 1 else n * t(n-1))
Please explain me that, maybe expand recursion?
the fin factorial is the (\t n -> if n == 1 ...) lambda
y is a so called fix-point combinator and it's used to enable recursive definitions in the lambda-calculus (it applies f to it's argument again and again recursively)
to understand how it works you can just do some evaluation by hand:
factorial 3
= y (\t n -> ...) 3
{ def y and y (\t n -> ...) = factorial by eta-red. }
= (\t n -> ...) factorial 3
{ t = factorial, n = 3 -> else case }
= 3 * factorial 2
= 3 * (y (\t n -> ...) 2)
= 3 * ((\t n -> ...) factorial 2)
= { t = factorial, n = 2 -> else case }
= 3 * (2 * factorial 1)
= 3 * (2 * (y (\t n -> ...) 1))
= 3 * (2 * ((\t n -> ...) factorial 1)))
{ t = factorial n = 1 -> then case }
= 3 * (2 * 1)
= 6
y is the fixed-point combinator, also known as the y-combinator. In
factorial = y (\t n -> if n == 1 then 1 else n * t(n-1))
the lambda (\t n -> if n == 1 then 1 else n * t(n-1)) is bound to f in the definition of y. You can then do the expansion:
(\t n -> if n == 1 then 1 else n * t(n-1)) (y (\t n -> if n == 1 then 1 else n * t(n-1)))
so inside the lambda, t will be bound to the lambda itself, which allows it to call itself recursively.
Perhaps it's easier if you write out the y combinator thus, with two eta-expansions:
y :: ((a->b) -> a->b) -> a->b
y f x a = f (\q a' -> y f q a') x a
So f basically gets the recursive call (with a' in place of a) as its first argument.
I am trying to implement the law of cosines function, and here is my code:
cosC :: [a] -> a
cosC sides
| length sides < 3 = 0
| otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
where x = head(tail(tail(sides)))
y = head(tail(sides))
z = head(sides)
But I get two errors:
No instance for (Fractional a)
arising from a use of `/'
In the expression: (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
In an equation for `cosC':
cosC sides
| length sides < 3 = 0
| otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
where
x = head (tail (tail (sides)))
y = head (tail (sides))
z = head (sides)
and
No instance for (Num a)
arising from the literal `2'
In the first argument of `(*)', namely `2'
In the first argument of `(*)', namely `2 * x'
In the second argument of `(/)', namely `(2 * x * y)'
Edit: I have fixed the sign typo in the law of cosines above. Thanks to Daniel Fischer for pointing that out.
You're trying to calculate numerical results out of general types a, that can't possibly work. (It's like trying to build a bridge not just for general road-vehicles but for general things, e.g. spaceships, skyscrapers, paper clips and neutron stars). Just add the Floating constraint to a:
cosC :: Floating a => [a] -> a
and you can perform any of the arithmetic operations you need for such a calculation. (Fractional is actually enough for this function, but you won't be able to calculate the arccos of the result then).
Unrelated to your problem, note that there's a much better way to decompose lists in Haskell:
cosC (x:y:z:_) = (x^2 + y^2 - z^2) / (2*x*y)
cosC _ = 0
is equivalent to your definition. Why are you taking the arguments as a list anyway? That's quite a Lisp-ish thing to do, in Haskell I'd prefer
cosC :: Floating a => a -> a -> a -> a
cosC x y z = (x^2 + y^2 - z^2) / (2*x*y)
cosC :: Fractional a => [a] -> a
And this is how you can find out (in ghci):
*Main> let fun [x, y, z] = (x * x + y * y + z * z) / (2 * x * y)
*Main> :type fun
fun :: Fractional a => [a] -> a
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.