2017-06-26 15 views
2

私はHaskellの非型の可変引数

m = Map.fromList [("a","b"), ("b","c"), ("c","d"), ("d","e")] 
f x m = fromMaybe "default value" $ Map.lookup x m 

lookup' x = f x m 

モナドは今、私は読者のモナドを作成したいリーダーで動作するようにしてみてください。

r = reader lookup' 
-- Non type variable argument: 
-- in the constraint MonadReader [Char] m 
-- When checking the inferred type: 
-- b :: forall (m :: * -> *). MonadReader [Char] m => m [Char] 

ソリューションは、型を定義することでした

r = reader lookup' :: Reader String String 

これはなぜ問題を解決しますか?

+0

'Control.Monad.Reader'の代わりに' Control.Monad.Trans.Reader'をインポートします。後者は、より簡潔なコードを作成するより一般的なインターフェイスを公開しますが、時には、あなたが持っているようなあいまいメッセージを引き起こすこともあります。この特定の種類のものについてもっと知るには、 'トランスフォーマー'と 'mtl'の違いを読んでください。 – Alec

答えて

3

すぐに問題が発生するのは、monomorphism restrictionです。このケースの手を振って説明すると、具体的なrを定義しているように見えるので、Haskellは型変数を持たない単一型のシグネチャを推論しようとします(r = reader lookup')。

reader :: MonadReader r m => (r -> a) -> m aをインポートしたので、Haskellはそのreader lookup' :: MonadReader [Char] m => m [Char]を推測します。残念ながら、これはではありません。 monomorphic - Haskellはあなたが望むものが正確にわからないmです。エラーメッセージには、タイプ変数mがあいまいです。

reader lookup' :: Reader String Stringのような明示的な型注釈を追加すると、この問題は解決されます。今度はm ~ Reader Stringを推測することができます。

関連する問題