I have following type:
newtype Moi s a =
Moi { runMoi :: s -> (a, s) }
the data constructor expects a function as the argument and it should return a tuple.
I tried following:
*OwnState> :t Moi (+1)
the compiler complains:
<interactive>:1:6: error:
* Occurs check: cannot construct the infinite type: s ~ (a, s)
Expected type: s -> (a, s)
Actual type: (a, s) -> (a, s)
* In the first argument of `Moi', namely `(+ 1)'
In the expression: Moi (+ 1)
First look at the type signature of (+1):
*OwnState> :t (+1)
(+1) :: Num a => a -> a
The type a has to be constraint to Num typeclass.
So when I write Moi (+1), what is going to happen, how the type is going to be substitute?
Let's analyze the error message as the next step:
Occurs check: cannot construct the infinite type: s ~ (a, s)
Tilde means ~ type equality and how the compiler comes to conclusion that s has the same type as (a, s)?
I suppose, the type substitution of example above works in this way:
n -> n "Type of (+1)
| |
s -> (a, s)
then s becomes to (a, s) and the proof s ~ (a, s) is true.
(a, s) -> (a, s)
But I can not see, why it is infinite type.