I am trying to understand how this factorial example works using the function fix :: (a -> a) -> a
.
factabs :: (Num a, Eq a) => (a -> a) -> a -> a
factabs fact 0 = 1
factabs fact x = x * fact (x-1)
f :: (Num a, Eq a) => a -> a
f = fix factabs
I do not see why fix factabs
has this type... fix
expects a function of type a -> a
, how can we apply it to a function of type (a -> a) -> a -> a
(a function that takes two parameters)? I am totally confused...
Basically I was trying to figure out how to convert the function limit
below to something that uses fix
. Would appreciate any help.
limit f n
| n == next = n
| otherwise = limit f next
where
next = f n
fix expects a function of type
a -> a
, how can we apply it to a function of type(a -> a) -> a -> a
(a function that takes two parameters)? I am totally confused...
That works because all Haskell functions take just one parameter. Even though we often think of this type...
(a -> a) -> a -> a
... as one of a function of two arguments, we can also read it like...
(a -> a) -> (a -> a)
... that is, one of a function that takes one argument (an a -> a
function) and produces a function of one argument (of type a
). Now if we take...
fix :: (b -> b) -> b
... we can see how factabs
fits it by replacing b
with (a -> a)
.
Basically I was trying to figure out how to convert the function
limit
below to something that usesfix
.
All you need to do is, starting from the original definition, replacing any recursive calls of limit
with an extra argument and passing this limit
-with-an-extra-argument to fix
(as you will see, the types will match with no further ado).