0
votes

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?

1
Unless this is an exercise, normals lists can hold functions.Carcigenicate
@Carcigenicate yes, I have to use my custom listjublikon
Hint: if Flist a contains a -> a functions, what does Flist (x->y) contain? Regardless... you shouldn't have run into the error you quote, you should have earlier run into a clearer to understand error when compiling apply. Let me guess: you didn't compile it with the type signature? Bad idea...leftaroundabout

1 Answers

3
votes

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.