I'm trying to create a function that composes a function f with a function g that takes multiple arguments.
c :: (a -> b) -> (c -> a) -> c -> b
c x y z = x(y(z))
lift = c c
(lift $ lift $ lift ... c)
creates the desired function:
*Main> (lift $ lift $ lift $ lift $ lift $ c) (\x -> x+2) (\x y z a b c -> x*y*z-(a*b*c)) 1 2 3 4 5 6
-112
However, when I attempt to define a function to produce a function that takes f, g, then n arguments (to save typing), the following error occurs:
cn 1 = c
cn k = lift (cn(k-1))
<interactive>:9:1: error:
* Occurs check: cannot construct the infinite type: a ~ c0 -> a
Expected type: t -> (a -> b) -> a -> b
Actual type: t -> (a -> b) -> (c0 -> a) -> c0 -> b
* Relevant bindings include
cn :: t -> (a -> b) -> a -> b (bound at <interactive>:9:1)
Why does this error occur, and how might I resolve it?
You cannot make polyvariadic functions in Haskell without typeclasses.
When you try to make a function that takes either one or two arguments, you try to make a function of type a -> b
and a -> p -> b
. Hence, the compiler must infer that the type b
is equivalent to p -> b
, so the type of the function becomes a -> p -> p -> p -> ...
. In other words, an infinite type.
A similar problem occurs when you try to make this function. The first line is fine:
cn 1 = c
This would imply something like cn :: Int -> (b -> c) -> (a -> b) -> a -> c
. However, we now have a problem in the second line:
cn k = lift (cn (k-1))
Since we know that cn :: Int -> (b -> c) -> (a -> b) -> a -> c
, we must infer that cn (k-1) :: (b -> c) -> (a -> b) -> a -> c
. However, since lift :: (x -> y -> z) -> x -> (w -> y) -> w -> z
, we see that the return value must be of type (b -> c) -> (w -> a -> b) -> w -> c
, which clashes with the original type declaration.
TL;DR: you can't change the type of a Haskell function/value via values. This means you can't write polyvariadic functions without certain tricks.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.