So I'm new to Haskell and trying to figure out why this code is not working as intended.
I want to make a function "run" that takes as input some function and returns that function applied to itself.
run::(t1->t2)->t2
run a = a a
The types included are supposed to be general because I want this to work on anything, but I'm getting and infinite type error when I try and I'm not sure why.
CodePudding user response:
You say a :: t1 -> t2
. This means its argument should have type t1
. Then you apply it to itself, a a
. This means its argument is a
.
So now we have an equation: the argument should have both the type t1
(because it is an argument to a
) and the type t1 -> t2
(because it is a
):
t1 ~ t1 -> t2
~ (t1 -> t2) -> t2
~ ((t1 -> t2) -> t2) -> t2
~ (((t1 -> t2) -> t2) -> t2) -> t2
~ ...
Each line follows from the previous by replacing t1
by the thing it's equal to, t1 -> t2
. No finite types satisfy the given equality.
CodePudding user response:
You write
run::(t1->t2)->t2
run a = a a
Because a
is the argument of the function,
a :: t1 -> t2
Now you're applying a
to a
. The argument of a
has type t1
, so we must have
a :: t1
The only this can make sense is if t1
is the same as t1 -> t2
. So that would mean
t1
= t1 -> t2
= (t1 -> t2) -> t2
= ((t1 -> t2) -> t2) -> t2
= ...
That's probably where your infinite type error comes from. I'm not sure why you don't get a simpler error saying that t1
is not the same as t1 -> t2
.
So ... you can't *exactly call a function with itself in Haskell. You can do some similar things, with some care. But how you do it will depend on exactly what you're trying to accomplish.