Haskell - この関連するタイプの例がより多くの推論が必要な理由を理解していない

StackOverflow https://stackoverflow.com/questions/7382171

質問

次のコードを検討してください。

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top