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
Let’s try to figure out the type of the first function:
Imagine
aisIntandfis normal addition. The second argument would be anInt. If you call e.g.gen (+) 3, the result is a function equivalent to(+3), which takes anIntand returns anInt. But your signature says that you just give back anInt.So basically the compiler complains because it expects an
a, and you give it ana->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 xThe second one is just a specialization of the identity function
id :: t -> t.The third one is similar to the first one.