I am trying to understand how this factorial example works using the function fix :: (a -> a) -> a.
Example:
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 uses fix.
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).
Just for the record, here is a version of limit function that I posted in my question that uses fix:
limit :: Eq a => (a -> a) -> a -> a
limit = fix (\g f x -> let x' = f x
in if x == x' then x else g f x')
Related
One of the exercises I am trying has defined a function as follows:
twice f x = f (f x)
When I print the type of twice I see:
Main> :t twice
twice :: (a -> a) -> a -> a
Not sure I understand the output here. So twice takes an input of type function (which is of type a -> a). Is this correct? If so then how was the f evaluated to be of type function (a -> a)? And then what is the return type of twice here?
twice f x = f (f x)
twice :: (a -> a) -> a -> a
it is like this.
f is of type a -> a, x is of type a, f (f x) is of type a.
You should pass f as a -> a function, such as * 2
Yes, it's correct.
f has a type of a -> a
It takes x which has a type of a and should be able to use his output again, so the output should be the same type as the input.
And twice has the same output type as a call from f, so a.
Which gives us this:
twice :: (a -> a) -> a -> a
twice f x = f (f x)
I am writing a function called mapper2 that applies a function to two lists:
mapper2 :: (a-> b -> c) -> [a] -> [b] -> [c]
mapper2 f (x:xs) (y:ys) = (f x y) : (mapper2 f xs ys)
mapper2 _ _ _ = []
I am able to compile the function but get an error when I apply it:
*Main> mapper2 (\x -> x*2) [2,4] [4,6]
<interactive>:4:1: error:
• Non type-variable argument in the constraint: Num (b -> c)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall b c. (Num (b -> c), Num b) => [c]
Can someone explain to me how to fix this and what the error means?
Silvio Mayolo has covered the main, practical part of the question, so I will stick to the technical details related to...
what the error means?
To begin with, the error is a bit hairy, but one thing that you can focus on at first is the Num (b -> c) bit. It indicates that you are somehow trying to use a function type (b -> c) as a number (i.e. an instance of Num), which is something that is almost never done intentionally (as we usually do not use functions as numbers). More often than not, when such things happen it is a sign that there is a mismatch in the number of arguments somewhere (which is the case here, as explained by Silvio Mayolo's answer). That said, what follows is an explanation of how the error comes about.
The first argument of mapper2 has type a -> b -> c or, equivalently, a -> (b -> c). When you pass...
(\x -> x * 2) :: Num z => z -> z
... to it, a -> (b -> c) and Num z => z -> z are matched (or, using the jargon, unified), so that the first z becomes a and the second z becomes b -> c. Since both z are supposed to be the same thing, a becomes b -> c as well, and so the type of (\x -> x * 2) is specialised to:
(\x -> x * 2) :: Num (b -> c) => (b -> c) -> (b -> c)
The error message Non type-variable argument in the constraint: Num (b -> c)
refers to how, unlike in e.g. Num x, there is something within the constraint that is not a type variable. In this case, it is function type constructor, ->. While turning on the FlexibleContexts extension, as the error message suggests, would allow that, there is no reason to do so here, as it still wouldn't be what you want (you have no intention of using functions as numbers). Furthermore, doing so in this case would just lead to another type error.
Look at mapper2's type.
mapper2 :: (a -> b -> c) -> [a] -> [b] -> [c]
Now look at the type of the function you're passing in.
(\x -> x * 2) :: Num a => a -> a
The mapper2 function expects a function of two arguments to be passed in, but your lambda only takes one argument.
I am new to Haskell and am trying to call a function which I got from:
http://www.haskell.org/haskellwiki/Functional_differentiation
derive :: (Fractional a) => a -> (a -> a) -> (a -> a)
derive h f x = (f (x+h) - f x) / h
I am having trouble understanding the parameters of the method and what h f x correspond to.
From what I understand:
h is a fractional
f is a function which takes in a fractional and returns a fractional
x ?? where does that come from?
however when I type in GHCi:
Prelude> let derive h f x = (f (x+h) - f x) / h
Prelude> :t derive
derive :: Fractional a => a -> (a -> a) -> a -> a
Prelude>
I get a different type out of it.
What is going on? Is this some kind of currying?
It is indeed currying. (Fractional a) => a -> (a -> a) -> (a -> a) and Fractional a => a -> (a -> a) -> a -> a are the same type because -> is right associative.
take add x y = x + y. Its type is Int -> Int -> Int ~ Int -> (Int -> Int). So add 5 is a function which takes an Int and adds 5 to it.
The reason that one might write the first form may be to put the emphasis on the usage of the curried form of a function.
Because -> is right associative, the type of derive could be written as
derive :: (Fractional a) => a -> (a -> a) -> a -> a
In other words,
derive :: (Fractional a) => a -> (a -> a) -> (a -> a)
equals
derive :: (Fractional a) => a -> (a -> a) -> a -> a
I think it makes what x means quite clear :-)
Ok, so the differentiation can be approximated as:
df(x)/dx = (f(x+h) - f(x)) / h , in the limit of h -> 0 at point x
where h is a small number. In Haskell, f(x) is written as f x. It takes and x and returns a number, just like f(x) takes a number and returns another. Your function for derivative is a direct translation. Here, f is the function you want to derive at point x, with the small number h.
So for the derivative, you provide the small number h, the function f and the point at which you want to calculate the derivative x. In Haskell,
derive h f x = ...
Not exactly. h is of type a, which could be anything, but it needs an instance Fractional. Fractional by itself is not a type, but a type class, i.e., interface the type must support.
f is a function that takes something of type a and returns something of the same type a. It should be the same a as before. Not some other instance of Fractional; the same one.
Having troubles with manually calculating types of given functions in Haskell for an exam at the weekend.
I understand the basics such as:
i x = x :: t -> t
k x y = x :: t -> t1 -> t
But having trouble on more complicated questions such as:
two f x = f (f x)
s x y z = x z (y z)
Any explanations would be much appreciated!
In those two examples the only hints you have as to the types of the functions come from observing the application going on. In Haskell application hardly has any syntax, so I'll rewrite them a bit more obviously.
two f x = f(f(x))
s x y z = x(z)(y(z))
We'll now discover the types of these functions through gradual refinement. For instance, beginning with two we know that it takes in two arguments and thus must have a type which agrees with the (more general) type
two :: a -> b -> c
We also know that the a type variable above actually corresponds to a function because f is being applied to both x and f(x).
two :: (a -> b) -> c -> d
Since f is applied to x we know that here a and c must be the same.
two :: (a -> b) -> a -> d
and since we apply f again to its result f(x) we know that the result type must be the same as the input type
two :: (a -> a) -> a -> b
And finally, the result of calling f is the total result of two so d must also equal a
two :: (a -> a) -> a -> a
This uses all of the information we have in the definition and is the most general type that is compatible with the definition of two.
We can do basically the same process for s. We know it has 3 arguments
s :: a -> b -> c -> d
We know that the first and second arguments are functions of some kind. We see the second argument applied to a single value and the first applied to two values.
s :: (a -> b -> c) -> (d -> e) -> f -> g
We also know that the first input to both functions are the same (namely, it's z each time). This lets us infer that a, d, and f are the same type
s :: (a -> b -> c) -> (a -> d) -> a -> e
We also know that the result of calling the second function is the second argument to the first function, so b and d must be the same.
s :: (a -> b -> c) -> (a -> b) -> a -> e
Finally, the result of fully applying the first function is the final result of s so c and e are the same
s :: (a -> b -> c) -> (a -> b) -> a -> c
While that might be a lot to digest and kind of a blur, the thing to emphasize is that the tools I've used to solve this problem are all primitive. Effectively, I introduce arrows (->) when I see that the type got applied to some values and thus must be a function of a certain number of arguments and I unify type variables by following the values through their expression. These are sufficient tools for inferring the types of simple functions like two and s.
Your two and s are what as known as higher level functions, because they take functions as arguments. You already have the tools to discern their types, you just have to be willing to be a bit more abstract about it.
If you're given the expression
f x
You know the type of f is a -> b with x :: a and f x :: b. If you see
f (f x)
Then you can deduce that the output type of (f x) is the same as the input type for f. This means that a ~ b, so f :: a -> a and x :: a. If we look at the type of two, we can deduce that it follows the pattern
two :: s -> t -> u
but the first argument to two is f, which has the type a -> a, so we can plug that in as
two :: (a -> a) -> t -> u
And x is the second argument with type a, so we can plug that in
two :: (a -> a) -> a -> u
And the return type is the same as the return type of f (f x), which has the return type of f, which has the return type of a, so if we plug that in we get the final type
two :: (a -> a) -> a -> a
For s, we can do similarly. We start off by saying s follows the form
s :: s -> t -> u -> v
since it has 3 arguments. The expression (y z) is function application, so y must have the type y :: a -> b, with z :: a. Plugging that in to s:
s :: s -> (a -> b) -> a -> v
Then we look at x z (y z). Since y z :: b and z :: a, x is a function of two arguments, the first of type a and the second of type b, with some unknown return type c, so we can plug that in as
s :: (a -> b -> c) -> (a -> b) -> a -> c
Let's look at
two f x = f (f x)
We will proceed by writing down what we know, using variables for anything we don't. Some of the things we know will be equations, and like in math, we will substitute around in the equations until we get something that we can't do anything else with.
Starting with the expression f x. f is a function, and its argument type is whatever x's type is, so:
x :: a -- a is a new variable
f :: a -> b -- b is a new variable
These two equations say exactly what I just said in the previous sentence. Also, we created the variable b which is the type of the result of the application:
f x :: b
Now let's move on to f (f x). So the argument type of f has to be the type of f x, which we know is b, so:
f :: b -> c -- c is a new variable
f (f x) :: c
But, of course, a function can only have one type, and we already have a type for f:
f :: a -> b -- from above
That means that
a = b
b = c
We've reached the top level expression now. So now let's look at the types of the input variables we've found together with the expression:
f :: a -> b
x :: a
f (f x) :: c
Now we go substituting around as much as we can, expressing it with as few variables as possible (but only using equalities that we have deduced). We'll try to do it all in terms of a.
f :: a -> b
= a -> a -- because b = a
x :: a
f (f x) :: c
= b -- because c = b
= a -- because b = a
And there we have it:
two :: (a -> a) -> a -> a
^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^
type of f type of x type of result
This is more verbose than necessary, because I repeated myself a lot, so that you could see the reasoning involved. There is a methodical way to do this, but I prefer to do it more like math, going along and discovering what I can. The methodical way usually gets me lost in a sea of variables (which is easy enough for a computer, but hard for my mortal human brain).
I hope this helped.
So I was playing around with Haskell today, thinking about autogeneration of function definitions given a type.
For example, the definition of the function
twoply :: (a -> b, a -> c) -> a -> (b, c)
is obvious to me given the type (if I rule out use of undefined :: a).
So then I came up with the following:
¢ :: a -> (a ->b) -> b
¢ = flip ($)
Which has the interesting property that
(¢) ¢ ($) :: a -> (a -> b) -> b
Which brings me to my question. Given the relation =::= for "has the same type as", does the statement x =::= x x ($) uniquely define the type of x? Must x =::= ¢, or does there exist another possible type for x?
I've tried to work backward from x =::= x x ($) to deduce x :: a -> (a -> b) -> b, but gotten bogged down.
x =::= x x ($) is also true for x = const, which has the type a -> b -> a. So it does not uniquely identify the type.
I'd just like add that you should look at http://hackage.haskell.org/package/djinn. It can take many type signatures and derive an implementation from them. If there's only one implementation possible for a type that djinn understands, it will produce it.
From the equation above, we can determine some of a type signature for x. X need not have this type, but it needs to at least unify with this type.
$ :: forall a b. (a -> b) -> a -> b
x :: t1 -> ((a -> b) -> a -> b) -> t1
Given that, it should be straightforward to write a multitude of implementations of x.