Inferring type of composed function Haskell - function

Im having trouble inferring the type of this function:
(foldr (.))
I know the types of:
(.) :: (b -> c) -> (a -> b) -> a -> c
foldr :: (a -> b -> b) -> b -> [a] -> b
But now i have no idea what to do.. Is there a method to always be able to infer the type in a systematic way? How would it apply to this case?

I usually follow these steps:
Write their types:
(.) :: (b -> c) -> (a -> b) -> a -> c
foldr :: (a -> b -> b) -> b -> [a] -> b
Make all the type variable name distinct:
(.) :: (b -> c) -> (a -> b) -> a -> c
foldr :: (x -> y -> y) -> y -> [x] -> y
Now since you are applying (.) to the first argument of foldr, you can infer the following relation between the types:
foldr :: ( x -> y -> y ) -> y -> [x] -> y
(.) :: (b -> c) -> (a -> b) -> (a -> c)
From the above you can infer the following relationship:
x ~ (b -> c)
y ~ (a -> b)
y ~ (a -> c)
From the above y, you can infer that both b and c should be same.
The type of foldr (.) should be:
foldr (.) :: y -> [x] -> y
Now replace y and x with the new derived ones, you will get the required type:
foldr (.) :: (a -> b) -> [b -> b] -> a -> b

Related

How to Implement functions from type signatures?

I have the following two type signatures in Haskell:
foo :: (a -> (a,b)) -> a -> [b]
bar :: (a -> b) -> (a -> b -> c) -> a -> c
I want to write a concrete implementation of these two functions but I'm really struggling to understand where to start.
I understand that foo takes a function (a -> (a,b)) and returns a and a list containing b.
And bar takes a function (b -> c) which returns a function (a -> b -> c) which finally returns a and c.
Can anyone show me an example of a concrete implementation?
How do I know where to start with something like this and what goes on the left side of the definition?
You have some misunderstandings there:
I understand that foo takes a function (a -> (a,b)) and returns a and a list containing b.
No, it doesn't return a. It expects it as another argument, in addition to that function.
And bar takes a function (b -> c) which returns a function (a -> b -> c) which finally returns a and c.
Same here. Given g :: a -> b, bar returns a function bar g :: (a -> b -> c) -> a -> c. This function, in turn, given a function h :: (a -> b -> c), returns a function of type a -> c. And so it goes.
It's just like playing with pieces of a puzzle:
foo :: (a -> (a,b)) -> a -> [b]
-- g :: a -> (a,b)
-- x :: a
-- g x :: (a,b)
foo g x = [b] where
(a,b) = g x
bar :: (a -> b) -> (a -> b -> c) -> a -> c
-- g :: a -> b
-- x :: a
-- g x :: b
-- h :: a -> b -> c
-- h x :: b -> c
-- h x (g x) :: c
bar g h x = c where
c = ....
There's not much free choice for us here. Although, there are more ways to get more values of type b, for foo. Instead of ignoring that a in (a,b) = g x, we can use it in more applications of g, so there actually are many more possibilities there, like
foo2 :: (a -> (a,b)) -> a -> [b]
foo2 g x = [b1,b2] where
(a1,b1) = g x
(a2,b2) = g a1
and many more. Still, the types guide the possible implementations. foo can even make use of foo in its implementation, according to the types:
foo3 :: (a -> (a,b)) -> a -> [b]
foo3 g x = b : bs where
(a,b) = g x
bs = ...
So now, with this implementation, the previous two become its special cases: foo g x === take 1 (foo3 g x) and foo2 g x === take 2 (foo3 g x). Having the most general definition is probably best.
In addition to #will-nes's answer, it will be useful to treat (->) as a right-associative infix operator. So something like f: a -> b -> c is the same as f: a -> (b -> c). So this is saying f is a function that takes a value of type a and returns you a value of type b -> c, which is, another function, one that takes a value of type b and returns you a value of type c.
So the types in your example can be re-written as follows
foo :: (a -> (a,b)) -> (a -> [b])
bar :: (a -> b) -> ((a -> (b -> c)) -> (a -> c))
Similarly, you can think of arguments to a function in pieces as well, as being left-associative (like + and -), though there's no explicit operator in this case. foo a b c d e is the same as ((((foo a) b) c) d) e. For example, let's say we have a function f: Int -> Int -> Int (which is the same as f: Int -> (Int -> Int)). You don't have to provide both arguments at once. So you can write g = f 1, which has the type (Int -> Int). And then you can provide an argument to g, like g 2, which has the type Int. f 1 2 and let g = f 1 in g 2 are more or less the same. Here's a more concrete example of how this works:
Prelude> f = (+)
Prelude> g = f 1
Prelude> g 2
3
Prelude> :t f
f :: Num a => a -> a -> a
Prelude> :t g
g :: Num a => a -> a
Prelude> :t g 2
g 2 :: Num a => a
In #will-nes's sample implementation examples, he defines the functions with all of the arguments up front, but you don't have to think of them that way. Just think of f: a -> b -> c as taking a value of type a and returning another function. While most of the methods you encounter will use all of their arguments up-front, there might be cases in which you don't want to do that. Here's an example:
veryExpensive :: A -> B
unstagedFun :: A -> (B -> C) -> C
unstagedFun a f = f (veryExpensive a)
stagedFun :: A -> (B -> C) -> C
stagedFun a = let b = veryExpensive a in \f -> f b
(You can also rewrite the latter as let b = veryExpensive a in ($ b))
Of course, with compiler optimizations, I wouldn't be surprised if the unstaged version staged automatically, but hopefully this offers some motivation for thinking of functions as not having multiple arguments, but rather, as a single argument, but they may return other functions that may themselves return functions (but also only take a single argument).

How to write my own Haskell sortOn function

I was wondering how to write my own sortOn function.
I made a sortBy function and an on function as shown bellow but can't figure out how to combine them and what additional code to add. sortOn is like sortBy but the given function (in here named comp) is applied only once for every element of the list
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
sortBy comp [] = []
sortBy comp [x] = [x]
sortBy comp (x:xs) = insert x (sortBy comp xs)
where
insert x [] = [x]
insert x (y:ys)
| (comp x y == LT) || (comp x y == EQ) = x:y:ys
| otherwise = y:(insert x ys)
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
on b f x y = b (f x) (f y)
Here's a hint.
If you have a list [a] and you just sort it, the sort function will implicitly make use of the Ord instance for a and specifically the function:
compare :: a -> a -> Ordering
to figure out the relative ordering of pairs of a elements.
Now, if you have a list [a] and a transformation function b, and you want to use sortOn to sort the list of the transformed values, you'll need to figure out the relative ordering of pairs of b elements. How will you do this? Well, you'll implicitly use the Ord instance for b and specifically the function:
compare :: b -> b -> Ordering
In other words, when you try to define:
sortOn :: (Ord b) => (a -> b) -> [a] -> [a]
sortOn f lst = ...
you'll have arguments of type:
f :: a -> b
lst :: [a]
and additional objects of type:
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
compare :: b -> b -> Ordering
Now, can you see how to put them together to define sortOn?
SPOILERS
Further hint: What's the type of compare `on` f?
Further further hint: It's a -> a -> Ordering.

Can this function be implemented?

Is there any implementation for this function?
foo :: (Monad m, Monad n) => m a -> n a -> (a -> a -> a) -> m (n a)
foo x y f = ...
Yes, and it can be given a more general type.
foo :: (Functor f, Functor g) => (a -> b -> c) -> f a -> g b -> f (g c)
foo f fx gy = fmap (\x -> fmap (f x) gy) fx

Haskell. Functions in Num expressions

I start to learn Haskell. While studying a tutorial I have found the following example that enables the usage of functions in arithmetic expressions:
module FunNat where
instance Num a => Num (t -> a) where
(+) = fun2 (+)
(*) = fun2 (*)
(-) = fun2 (-)
abs = fun1 abs
signum = fun1 signum
fromInteger = const . fromInteger
fun1 :: (a -> b) -> ((t -> a) -> (t -> b))
fun1 = (.)
fun2 :: (a -> b -> c) -> ((t -> a) -> (t -> b) -> (t -> c))
fun2 op a b = \t -> a t `op` b t
The example works. But I can not understand how the (+) function is transformed into the function of two arguments. As I can understand each (+) is substituted with fun2 (+). And fun2 is equivalent to the function of one argument \t -> a t 'op' b t, but we should have a function of two arguments (something like (\t1 t2 -> (\x -> x ) t1 + (\x -> x) t2) ). I think that here some basic concepts of Haskell typing should be applied but I do not know what they are.
EDIT 1
I understand that fun2 is a function of three arguments. I can't understand internal expression transformation. I'm reasoning in the following way: (+) 3 4 = (+) (\x->3) (\x->4) = fun2 (+) (\x->3) (\x->4) = \t -> (\x->3) t + (\x->4) t
What is this t? Or where am I wrong in my reasoning? May be it is necessary to think another way?
EDIT 2
I think that I have reached some understanding of the issue (thanks you all!). So:
When we write (+) 3 4 - in this case a simple operation from Num is used, no special features from FunNat. To use (+) from FunNat it is necessary to write fun2 (+) 3 4 or fun2 (+) (\x -> 3) (\x -> 4). But these expressions expect any third parameter to be evaluated;
To demonstrate specific features from FunNat we may use the following example ((*)-(+)) (taken from tutorial) or in other form - (-) (*) (+). Both expressions take two arguments. In this case we have: ((*)-(+)) = fun2 (-) (*) (+) = \t -> (*) t - (+) t = \t -> (\t1 t2 -> t1 * t2) t - (\t1 t2 -> t1 + t2) t = (\t t2 -> t * t2) - (\t t2 -> t + t2) = \t t2 -> (t * t2) - (t + t2). The final expression expects just Num. I hope that all these are correct
As it was explained in tutorial, but I can't understand what for, the possibility to use (*) and (+) as parameters for fun2 that expects (t->a) is based on the following (taken from tutorial): t1 -> t2 -> a = t1->a' where a' = t2 -> a. Here curring is used.
So all necessary facts were on the surface but I do not take into consideration the non-trivial mechanism of type inference.
The type of (+) is Num a => a -> a -> a. Since you're creating an instance of Num for the type Num a => t -> a, consider the explicit signature
(+) :: Num a => (t -> a) -> (t -> a) -> (t -> a) (1)
or equivalently (by currying)
(+) :: Num a => (t -> a) -> (t -> a) -> t -> a (2)
What this says is: "If you give me 2 strategies for producing a Num a => a from a t, I can create a new strategy for producing a Num a => a from a t by using the Num.(+) instance of the a's"
I think the part that has you confused is that this specific (+) can be viewed as a function of 2 arguments which returns a function (1), or a function of 3 arguments which returns a value (2). Since functions in Haskell are curried, these are really the same thing.
In type signatures parentheses associate to the right, so:
f :: a -> (b -> c -> d)
is the same as:
f :: a -> b -> c -> d
So the parens indicated below are redundant:
fun2 :: (a -> b -> c) -> ((t -> a) -> (t -> b) -> (t -> c))
^ ^
and removing them leaves:
fun2 :: (a -> b -> c) -> (t -> a) -> (t -> b) -> (t -> c)
arg1 arg2 arg3

How does fmap fmap apply to functions (as arguments)?

I am trying to understand how fmap fmap applies to a function like say (*3).
The type of fmap fmap:
(fmap fmap):: (Functor f1, Functor f) => f (a -> b) -> f (f1 a -> f1 b)
Type of (*3):
(*3) :: Num a => a -> a
Which means that the signature a -> a corresponds to f (a -> b), right?
Prelude> :t (fmap fmap (*3))
(fmap fmap (*3)):: (Num (a -> b), Functor f) => (a -> b) -> f a -> f b
I have tried creating a simple test:
test :: (Functor f) => f (a -> b) -> Bool
test f = True
And feeding (*3) into it, but I get:
*Main> :t (test (*3))
<interactive>:1:8:
No instance for (Num (a0 -> b0)) arising from a use of ‘*’
In the first argument of ‘test’, namely ‘(* 3)’
In the expression: (test (* 3))
Why is that happening?
Polymorphism is dangerous when you do not know what you are doing. Both fmap and (*) are polymorphic functions and using them blindly can lead to very confusing (and possibly incorrect) code. I have answered a similar question before:
What is happening when I compose * with + in Haskell?
In such cases, I believe that looking at the types of values can help you figure out where you are going wrong and how to rectify the problem. Let's start with the type signature of fmap:
fmap :: Functor f => (a -> b) -> f a -> f b
|______| |________|
| |
domain codomain
The type signature of fmap is easy to understand. It lifts a function from a to b into the context of a functor, whatever that functor may be (e.g. list, maybe, either, etc.).
The words "domain" and "codomain" just mean "input" and "output" respectively. Anyway, let's see what happens when we apply fmap to fmap:
fmap :: Functor f => (a -> b) -> f a -> f b
|______|
|
fmap :: Functor g => (x -> y) -> g x -> g y
|______| |________|
| |
a -> b
As you can see, a := x -> y and b := g x -> g y. In addition, the Functor g constraint is added. This gives us the type signature of fmap fmap:
fmap fmap :: (Functor f, Functor g) => f (x -> y) -> f (g x -> g y)
So, what does fmap fmap do? The first fmap has lifted the second fmap into the context of a functor f. Let's say that f is Maybe. Hence, on specializing:
fmap fmap :: Functor g => Maybe (x -> y) -> Maybe (g x -> g y)
Hence fmap fmap must be applied to a Maybe value with a function inside it. What fmap fmap does is that it lifts the function inside the Maybe value into the context of another functor g. Let's say that g is []. Hence, on specializing:
fmap fmap :: Maybe (x -> y) -> Maybe ([x] -> [y])
If we apply fmap fmap to Nothing then we get Nothing. However, if we apply it to Just (+1) then we get a function that increments every number of a list, wrapped in a Just constructor (i.e. we get Just (fmap (+1))).
However, fmap fmap is more general. What it actually does it that it looks inside a functor f (whatever f may be) and lifts the function(s) inside f into the context of another functor g.
So far so good. So what's the problem? The problem is when you apply fmap fmap to (*3). This is stupid and dangerous, like drinking and driving. Let me tell you why it's stupid and dangerous. Take a look at the type signature of (*3):
(*3) :: Num a => a -> a
When you apply fmap fmap to (*3) then the functor f is specialized to (->) r (i.e. a function). A function is a valid functor. The fmap function for (->) r is simply function composition. Hence, the type of fmap fmap on specializing is:
fmap fmap :: Functor g => (r -> x -> y) -> r -> g x -> g y
-- or
(.) fmap :: Functor g => (r -> x -> y) -> r -> g x -> g y
|___________|
|
(*3) :: Num a => a -> a
| |
| ------
| | |
r -> x -> y
Do you see why it's stupid and dangerous?
It's stupid because you are applying a function which expects an input function with two arguments (r -> x -> y) to a function with only one argument, (*3) :: Num a => a -> a.
It's dangerous because the output of (*3) is polymorphic. Hence, the compiler doesn't tell you that you are doing something stupid. Luckily, because the output is bounded you get a type constraint Num (x -> y) which should indicate that you have gone wrong somewhere.
Working out the types, r := a := x -> y. Hence, we get the following type signature:
fmap . (*3) :: (Num (x -> y), Functor g) => (x -> y) -> g x -> g y
Let me show you why it's wrong using values:
fmap . (*3)
= \x -> fmap (x * 3)
|_____|
|
+--> You are trying to lift a number into the context of a functor!
What you really want to do is apply fmap fmap to (*), which is a binary function:
(.) fmap :: Functor g => (r -> x -> y) -> r -> g x -> g y
|___________|
|
(*) :: Num a => a -> a -> a
| | |
r -> x -> y
Hence, r := x := y := a. This gives you the type signature:
fmap . (*) :: (Num a, Functor g) => a -> g a -> g a
This makes even more sense when you see the values:
fmap . (*)
= \x -> fmap (x *)
Hence, fmap fmap (*) 3 is simply fmap (3*).
Finally, you have the same problem with your test function:
test :: Functor f => f (a -> b) -> Bool
On specializing functor f to (->) r we get:
test :: (r -> a -> b) -> Bool
|___________|
|
(*3) :: Num x => x -> x
| |
| ------
| | |
r -> a -> b
Hence, r := x := a -> b. Thus we get type signature:
test (*3) :: Num (a -> b) => Bool
Since neither a nor b appear in the output type, the constraint Num (a -> b) must be resolved immediately. If a or b appeared in the output type then they could be specialized and a different instance of Num (a -> b) could be chosen. However, because they don't appear in the output type the compiler has to decide which instance of Num (a -> b) to choose immediately; and because Num (a -> b) is a stupid constraint which doesn't have any instance, the compiler throws an error.
If you try test (*) then you won't get any error, for the same reason that I mentioned above.