This is a problem with matching templates + rankntypes.
GHC tells m to be of type ST ??? a ST ??? a where ??? is a type variable that can be combined with anything and must be combined with something *. Therefore, we pass it to runST , and runST wants ST sa , so m combines with it, and ??? combined with s . But wait, now we are teaming up with s outside the area where s defines the scope, so itβs a disaster.
A simpler example:
test (M m) = (m :: forall t . ST ta) `seq` ()
And again, we get the same error, because we are trying to combine with type m with t , but t is too small.
The simplest solution is to simply not create this type variable with
test m = runST (unM m)
here unM returns a good and true polymorphic ST that satisfies runST . You can use let because it is polymorphic by default, but since -XTypeFamilies will make it monomorphic, it will explode just like pattern matching as you discovered.
** It seems that m monomorphic. let is polymorphic without type families, so I suspect this is what happens. It behaves like
test :: forall a. (forall t. M ta) -> () test (M m) = (m :: ST Bool a) `seq` (m :: ST Int a) `seq` ()
Errors trying to unify Bool and Int , as you would expect from a variable of monomorphic type. Why does any strange type error that I find seem to hide some kind of type of monomorphic type.
jozefg
source share