Reputation:
What is the difference(s) between them?
(i)
gen :: (a -> a -> a ) -> a -> a
gen f x = f x
(ii)
gen :: (a -> a ) -> a -> a
gen f x = f x
(iii)
gen :: (a -> a -> a -> a ) -> a -> a
gen f x = f x
first one gives error : "cannot construct infinite ... "
second one is work
third one not work
Upvotes: 1
Views: 87
Reputation: 54584
Let's try to figure out the type of the first function:
Imagine a
is Int
and f
is normal addition. The second argument would be an Int
. If you call e.g. gen (+) 3
, the result is a function equivalent to (+3)
, which takes an Int
and returns an Int
. But your signature says that you just give back an Int
.
So basically the compiler complains because it expects an a
, and you give it an a->a
, and there is no way to unify these types.
To fix it, you could either correct the signature, which would be gen :: (a -> a -> a ) -> a -> (a -> a)
, or to change the definition, e.g. gen f x = f x x
The second one is just a specialization of the identity function id :: t -> t
.
The third one is similar to the first one.
Upvotes: 2