A function which compiles and cabal repl
even indicates what a specific type should be (rel
) produces an error if the inferred type is included in the code.
coords2faces :: (MorphsHQ rel, Eq rel, Eq obj, Ord obj) => State (Store obj rel) [(obj, obj)]
coords2faces = do
f <- rel3 (hqFace :: rel)
return f
How to include a type in code in such a case?
The error message is
app/TheMain.hs:107:16: error:
• Could not deduce (MorphsHQ rel1) arising from a use of ‘hqFace’
from the context: (MorphsHQ rel, Eq rel, Ord obj)
bound by the type signature for:
coords2faces :: forall rel obj.
(MorphsHQ rel, Eq rel, Eq obj, Ord obj) =>
State (Store obj rel) [(obj, obj)]
at app/TheMain.hs:105:1-98
Possible fix:
add (MorphsHQ rel1) to the context of
an expression type signature:
forall rel1. rel1
• In the first argument of ‘rel3’, namely ‘(hqFace :: rel)’
In a stmt of a 'do' block: f <- rel3 (hqFace :: rel)
In the expression:
do f <- rel3 (hqFace :: rel)
return f
|
107 | f <- rel3 (hqFace :: rel)
CodePudding user response:
This is because the rel
in the type declared for coords2faces
is not the same as the rel
in the type declared for hqFace
. To make this more obvious, you can see that the compiler renamed the type variable to rel1
in the error message. By default, type variables in separate signatures are always independent.
In order to make the code compile, you can either remove the type signature for hqFace
,
coords2faces :: (MorphsHQ rel, Eq rel, Eq obj, Ord obj) => State (Store obj rel) [(obj, obj)]
coords2faces = do
f <- rel3 hqFace
return f
or you can enable the ScopedTypeVariables
language extension and declare the rel
type variable in a forall
to specify the scope.
{-# LANGUAGE ScopedTypeVariables #-}
coords2faces :: forall rel . (MorphsHQ rel, Eq rel, Eq obj, Ord obj) => State (Store obj rel) [(obj, obj)]
coords2faces = do
f <- rel3 (hqFace :: rel)
return f