Reputation: 3447
I have a custom data type Flist
containing functions. In the next step I would like to use the Flist myFunctions
in apply
.
Note: This is an exercise, so I have to use a custom list
data Flist a = Nil | Cons (a -> a) (Flist a)
myFunctions :: Flist (Integer -> Integer)
myFunctions = (Cons (\y x -> x + 1) ( Cons (\x w -> w + 1) (Nil)))
apply :: Flist (a -> a) -> b -> b
apply Nil b = b
apply (f `Cons` xs) b = apply xs (f b)
The call should look like that: apply myFunctions 1
returns 3
I get the error:
- No instance for (Num (Integer -> Integer)) arising from the literal `2' (maybe you haven't applied a function to enough arguments?)
- In the second argument of 'apply', namely '2' In the expression: apply myFunctions 2 In an equation for 'it': it = apply myFunctions 2
Question: I do not see my mistake. Why should I have applied not enough arguments to the function? I pass a Flist with functions that get an Int and return an Int. Additionally another Int is passed and that should be it. What is still missing here?
Upvotes: 1
Views: 1037
Reputation: 85767
There are several issues with your code.
You have
data Flist a = Nil | Cons (a -> a) (Flist a)
-- ^ ^^^^^^
So if you have a function f :: Integer -> Integer
, then Cons f Nil
has type Flist Integer
, not Flist (Integer -> Integer)
.
In fact, a Flist (Integer -> Integer)
would be a list of functions of type (Integer -> Integer) -> (Integer -> Integer)
.
That means myFunctions :: Flist (Integer -> Integer)
has the wrong type. If you fix that, you'll discover that the code for it isn't quite right either.
Then there's apply :: Flist (a -> a) -> b -> b
. This is another instance of the above problem (one layer of "function-ness" too many). Changing that to apply :: Flist a -> b -> b
reveals another problem: You do (f b)
where f :: a -> a
and b :: b
. But a
and b
are different type variables and (at least potentially) different. To allow this function application, it would have to be apply :: Flist a -> a -> a
.
Upvotes: 3