Haskell - この関連するタイプの例がより多くの推論が必要な理由を理解していない
-
29-10-2019 - |
質問
次のコードを検討してください。
data MyBaseExpr α where
ConstE :: Show α => α -> MyBaseExpr α
class Monad 𝔪 => MyMonadCls 𝔪 where
type ExprTyp 𝔪 :: * -> *
var :: String -> ExprTyp 𝔪 α -> 𝔪 (ExprTyp 𝔪 α)
expTypArg :: forall 𝔪 α. MyMonadCls 𝔪 => ExprTyp 𝔪 α -> 𝔪 α
expTypArg a = undefined
-- dummy type which will be used as an instance
newtype A 𝔪 α = A (𝔪 α)
次に、exptypearg関数を使用してインスタンスを作成しようとする場合、
instance forall 𝔪. (Monad 𝔪, Monad (A 𝔪)) => MyMonadCls (A 𝔪) where
type ExprTyp (A 𝔪) = MyBaseExpr
var nme init@(expTypArg -> typb) =
return init
コンパイラは文句を言います
Couldn't match type `ExprTyp 𝔪0' with `MyBaseExpr'
Expected type: ExprTyp (A 𝔪) α
Actual type: ExprTyp 𝔪0 α
しかし、スコープ型の式を追加すると、
instance forall 𝔪. (Monad 𝔪, Monad (A 𝔪)) => MyMonadCls (A 𝔪) where
type ExprTyp (A 𝔪) = MyBaseExpr
var nme init@((expTypArg :: MyMonadCls (A 𝔪) =>
ExprTyp (A 𝔪) α ->
(A 𝔪 α)) -> typb) =
return init
その後、それは正常に解決します。問題解決は何ですか ExprTyp == MyBaseExpr
為に expTypArg
?
編集
どうもありがとう、ダニエル!これは、口頭のいくつかを取り除く方法です。 𝔪
実施する必要があります。
ignore_comp :: 𝔪 α -> 𝔪 β -> 𝔪 β
ignore_comp a b = b
instance forall 𝔪. (Monad 𝔪, Monad (A 𝔪)) => MyMonadCls (A 𝔪) where
type ExprTyp (A 𝔪) = MyBaseExpr
var nme init@(expTypArg -> typb) =
typb `ignore_comp`
return init
解決
ExprTypは(必ずしも)無視型関数ではありません。これは、タイプのものを手渡されることを意味します ExprType m
ネズミはしません m
- 別のものもあるかもしれません n
そのような ExprType n = ExprType m
. 。これにより、タイプが作成されます expTypArg
少し注意が必要です:それは同じ方法で、return-ype Polymorphismを使用します。 read
そうするので、あなたがしなければならないのと同じ状況でその結果に追加のタイプの注釈を与える必要があります read
.
所属していません StackOverflow