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.
Related
I am struggling with an exercise in R. Bird's functional programming book that asks for an example of a function with type (num -> num) -> num
The best I can come up with is a polymorphic type
func1 f = f 3
:t func1
func1 :: Num t1 => (t1 -> t2) -> t2
The problem I am having is that I can't specify the return type of f, so the type remains (num -> t2) -> t2.
My attempt to force the return type of f is as follows:
square x = x * x
:t func1 square
func1 square :: Num t2 => t2 -> t2
Because of course if I try to find the type of func1 ∘ square it will just be num -> num
If it is enough to give a function which can be assigned that type, then yours is already enough. That is, the following type-checks just fine:
func1 :: Num a => (a -> a) -> a
func1 f = f 3
If, on the other hand, you want a function which is inferred to have that type, then you need to do some trickery. What we want to do here is to specify that the result of f 3 and the 3 that we fed in have the same type. The standard way to force two terms to have the same type is to use asTypeOf, which is implemented this way:
asTypeOf :: a -> a -> a
asTypeOf x _ = x
So let's try:
> :t \f -> f 3 `asTypeOf` 3
(Num a, Num t) => (t -> a) -> a
Unfortunately for us, this doesn't work, because the 3 in f 3 and the standalone 3 are inferred to be using potentially different instances of Num. Still, it is a bit closer than \f -> f 3 was -- note the new Num a constraint on the output that we didn't have before. An obvious next idea is to let-bind a variable to 3 and reuse that variable as the argument to both f and asTypeOf; surely then GHC will get the picture that f's argument and result have the same type, right?
> :t \f -> let x = 3 in f x `asTypeOf` x
(Num a, Num t) => (t -> a) -> a
Drat. Turns out that lets do what's called "let generalization"; the x will be just as polymorphic as the 3 was, and can be specialized to different types at different use sites. Usually this is a nice feature, but because we're doing an unnatural exercise we need to do unnatural things...
Okay, next idea: some lambda calculi do not include a let, and when you need one, instead of writing let a = b in c, you write (\a -> c) b. This is especially interesting for us because Haskell uses a specially-restricted kind of polymorphism that means that inside c, the type of a is monomorphic. So:
> :t \f -> (\x -> f x `asTypeOf` x) 3
Num a => (a -> a) -> a
And now you complain that asTypeOf is cheating, because it uses a type declaration that doesn't match its inferred type, and the whole point of the exercise was to get the right type through inference alone. (If we were okay with using type declarations that don't match the inferred type, we could have stopped at func1 :: Num a => (a -> a) -> a; func1 f = f 3 from way back at the beginning!) Okay, no problem: there's another standardish way to force the types of two expressions to unify, namely, by putting them in a list together. So:
> :t \f -> (\x -> head [f x, x]) 3
Num a => (a -> a) -> a
Phew, now we're finally at a place where we could in principle build, from the ground up, all the tools needed to get a term of the right type without any type declarations.
func1 f = let x = f x in x This is a partial function, it technically has the type you want and you should be aware of what they are and how they work in haskell.
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')
I have the applicative <$> operator more or less figured out, but I can't understand the signature I'm getting with the following example:
ghci> let f x y z = x + y + z -- f::Num a => a -> a -> a -> a
ghci> f <$> Just 2 <*> Just 3 <*> Just 4
Just 9
This result I understand, but when checking the following type:
ghci> :t (<$> f)
(<$> f) :: Num a => ((a -> a -> a) -> b) -> a -> b --This makes no sense to me
That signature I would understand as : a function that takes a (a -> a- > a) -> b function and an a as parameters and returns a b. According to this reasoning , I should call this like :
(<$>f) f 4
which would result in an Integer.
Obviously this is not true, so can you please help me understand how to read the type of (<$> f)?
a function that takes a (a -> a- > a) -> b function and an a as parameters and returns a b.
This is correct.
According to this reasoning , I should call this like :
(<$>f) f 4
which would result in an Integer.
No, because f does not have type (a -> a -> a) -> b or one compatible with it. Instead it has type Num a => a -> a -> a -> a. That is, f takes three numbers and produces a number, whereas we're looking for a function that takes a function (of type a -> a -> a) as its first argument.
<$> takes as a second argument something of type g b, where g is any applicative functor.
You are passing f :: Num a => a -> a -> a -> a as a second argument. Let's ignore the Num a context to keep things simple.
Hence, we look for g,b such that g b = a -> a -> a -> a.
Let's write the type of f in prefix form:
f :: (->) a ((->) a ((->) a a)) = g b
Hence, g = (->) a and b = ((->) a ((->) a a)). The latter is b = a -> a -> a in infix form.
It happens that (->) a is an applicative functor, so <$> f type checks. Note however that <$> is used on a completely different functor than the Maybe one you were using in your examples. Hence the confusion.
TL;DR: overloaded identifiers can shapeshift to many things adapting to their contexts, possibly in some unexpected way.
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.
We're used to having universally quantified types for polymorphic functions. Existentially quantified types are used much less often. How can we express existentially quantified types using universal type quantifiers?
It turns out that existential types are just a special case of Σ-types (sigma types). What are they?
Sigma types
Just as Π-types (pi types) generalise our ordinary function types, allowing the resulting type to depend on the value of its argument, Σ-types generalise pairs, allowing the type of second component to depend on the value of the first one.
In a made-up Haskell-like syntax, Σ-type would look like this:
data Sigma (a :: *) (b :: a -> *)
= SigmaIntro
{ fst :: a
, snd :: b fst
}
-- special case is a non-dependent pair
type Pair a b = Sigma a (\_ -> b)
Assuming * :: * (i.e. the inconsistent Set : Set), we can define exists a. a as:
Sigma * (\a -> a)
The first component is a type and the second one is a value of that type. Some examples:
foo, bar :: Sigma * (\a -> a)
foo = SigmaIntro Int 4
bar = SigmaIntro Char 'a'
exists a. a is fairly useless - we have no idea what type is inside, so the only operations that can work with it are type-agnostic functions such as id or const. Let's extend it to exists a. F a or even exists a. Show a => F a. Given F :: * -> *, the first case is:
Sigma * F -- or Sigma * (\a -> F a)
The second one is a bit trickier. We cannot just take a Show a type class instance and put it somewhere inside. However, if we are given a Show a dictionary (of type ShowDictionary a), we can pack it with the actual value:
Sigma * (\a -> (ShowDictionary a, F a))
-- inside is a pair of "F a" and "Show a" dictionary
This is a bit inconvenient to work with and assumes that we have a Show dictionary around, but it works. Packing the dictionary along is actually what GHC does when compiling existential types, so we could define a shortcut to have it more convenient, but that's another story. As we will learn soon enough, the encoding doesn't actually suffer from this problem.
Digression: thanks to constraint kinds, it's possible to reify the type class into concrete data type. First, we need some language pragmas and one import:
{-# LANGUAGE ConstraintKinds, GADTs, KindSignatures #-}
import GHC.Exts -- for Constraint
GADTs already give us the option to pack a type class along with the constructor, for example:
data BST a where
Nil :: BST a
Node :: Ord a => a -> BST a -> BST a -> BST a
However, we can go one step further:
data Dict :: Constraint -> * where
D :: ctx => Dict ctx
It works much like the BST example above: pattern matching on D :: Dict ctx gives us access to the whole context ctx:
show' :: Dict (Show a) -> a -> String
show' D = show
(.+) :: Dict (Num a) -> a -> a -> a
(.+) D = (+)
We also get quite natural generalisation for existential types that quantify over more type variables, such as exists a b. F a b.
Sigma * (\a -> Sigma * (\b -> F a b))
-- or we could use Sigma just once
Sigma (*, *) (\(a, b) -> F a b)
-- though this looks a bit strange
The encoding
Now, the question is: can we encode Σ-types with just Π-types? If yes, then the existential type encoding is just a special case. In all glory, I present you the actual encoding:
newtype SigmaEncoded (a :: *) (b :: a -> *)
= SigmaEncoded (forall r. ((x :: a) -> b x -> r) -> r)
There are some interesting parallels. Since dependent pairs represent existential quantification and from classical logic we know that:
(∃x)R(x) ⇔ ¬(∀x)¬R(x) ⇔ (∀x)(R(x) → ⊥) → ⊥
forall r. r is almost ⊥, so with a bit of rewriting we get:
(∀x)(R(x) → r) → r
And finally, representing universal quantification as a dependent function:
forall r. ((x :: a) -> R x -> r) -> r
Also, let's take a look at the type of Church-encoded pairs. We get a very similar looking type:
Pair a b ~ forall r. (a -> b -> r) -> r
We just have to express the fact that b may depend on the value of a, which we can do by using dependent function. And again, we get the same type.
The corresponding encoding/decoding functions are:
encode :: Sigma a b -> SigmaEncoded a b
encode (SigmaIntro a b) = SigmaEncoded (\f -> f a b)
decode :: SigmaEncoded a b -> Sigma a b
decode (SigmaEncoded f) = f SigmaIntro
-- recall that SigmaIntro is a constructor
The special case actually simplifies things enough that it becomes expressible in Haskell, let's take a look:
newtype ExistsEncoded (F :: * -> *)
= ExistsEncoded (forall r. ((x :: *) -> (ShowDictionary x, F x) -> r) -> r)
-- simplify a bit
= ExistsEncoded (forall r. (forall x. (ShowDictionary x, F x) -> r) -> r)
-- curry (ShowDictionary x, F x) -> r
= ExistsEncoded (forall r. (forall x. ShowDictionary x -> F x -> r) -> r)
-- and use the actual type class
= ExistsEncoded (forall r. (forall x. Show x => F x -> r) -> r)
Note that we can view f :: (x :: *) -> x -> x as f :: forall x. x -> x. That is, a function with extra * argument behaves as a polymorphic function.
And some examples:
showEx :: ExistsEncoded [] -> String
showEx (ExistsEncoded f) = f show
someList :: ExistsEncoded []
someList = ExistsEncoded $ \f -> f [1]
showEx someList == "[1]"
Notice that someList is actually constructed via encode, but we dropped the a argument. That's because Haskell will infer what x in the forall x. part you actually mean.
From Π to Σ?
Strangely enough (although out of the scope of this question), you can encode Π-types via Σ-types and regular function types:
newtype PiEncoded (a :: *) (b :: a -> *)
= PiEncoded (forall r. Sigma a (\x -> b x -> r) -> r)
-- \x -> is lambda introduction, b x -> r is a function type
-- a bit confusing, I know
encode :: ((x :: a) -> b x) -> PiEncoded a b
encode f = PiEncoded $ \sigma -> case sigma of
SigmaIntro a bToR -> bToR (f a)
decode :: PiEncoded a b -> (x :: a) -> b x
decode (PiEncoded f) x = f (SigmaIntro x (\b -> b))
I found an anwer in Proofs and Types by Jean-Yves Girard, Yves Lafont and Paul Taylor.
Imagine we have some one-argument type t :: * -> * and construct an existential type that holds t a for some a: exists a. t a. What can we do with such a type? In order to compute something out of it we need a function that can accept t a for arbitrary a, that means a function of type forall a. t a -> b. Knowing this, we can encode an existential type simply as a function that takes functions of type forall a. t a -> b, supplies the existential value to them and returns the result b:
{-# LANGUAGE RankNTypes #-}
newtype Exists t = Exists (forall b. (forall a. t a -> b) -> b)
Creating an existential value is now easy:
exists :: t a -> Exists t
exists x = Exists (\f -> f x)
And if we want to unpack the existential value, we just apply its content to a function that produces the result:
unexists :: (forall a. t a -> b) -> Exists t -> b
unexists f (Exists e) = e f
However, purely existential types are of very little use. We cannot do anything reasonable with a value we know nothing about. More often we need an existential type with a type class constraint. The procedure is just the same, we just add a type class constraint for a. For example:
newtype ExistsShow t = ExistsShow (forall b. (forall a. Show a => t a -> b) -> b)
existsShow :: Show a => t a -> ExistsShow t
existsShow x = ExistsShow (\f -> f x)
unexistsShow :: (forall a. Show a => t a -> b) -> ExistsShow t -> b
unexistsShow f (ExistsShow e) = e f
Note: Using existential quantification in functional programs is often considered a code-smell. It can indicate that we haven't liberated ourselves from OO thinking.