2011-12-03 4 views
5

私はHeinrich Apfelmusのoperational monadを使用しています。 結果タイプのモナドでインタープリタをパラメータ化したいと思います。 私のコードの次のバージョンがコンパイルされます。 任意のモナドに通訳を持つ操作モナ

{-# LANGUAGE GADTs #-} 

import Control.Monad.Operational 

data EloI a where 
    Display :: Int -> EloI() 

type Elo a = Program EloI a 

interpret :: Monad m => (Int -> m()) 
        -> Elo a 
        -> Int 
        -> m a 
interpret display = interp 
    where 
    interp :: Monad m => Elo a -> Int -> m a 
    interp = eval . view 
    eval :: Monad m => ProgramView EloI a -> Int -> m a 
    eval (Display i :>>= is) s = interp (is()) s 

は、今私はもう成功しない

eval (Display i :>>= is) s = display i >> interp (is()) s 

と型推論への最後の行を変更し、私は

ができませんでした出力を得ます(モナドm)
の解釈:: Monad m =>(Int - > m()) - > Elo a - > Int - > ma (.. 。)

interpのタイプシグネチャを削除すると、エラーが発生します(a1〜aを推測できませんでした)。
すべてのmをIOに変更すると(操作モナドのtic tac toeの例のように)、再びコンパイルされます。
GHCにヒントを提供することはできますか?私はこの柔軟性が必要であるとは確信できません。

答えて

8

ローカルタイプのシグニチャのmは新しいタイプの変数なので、のいずれかのモナドで動作することが約束されています。 displayを使用する場合、evalは、特定のモナドdisplayでのみ使用できます。私は通常、ローカル型シグネチャを使用していないalthaughそれはので)()はa)のローカル型シグネチャを削除する場合は動作、またはb)私も試していない範囲

{-# LANGUAGE ScopedTypeVariables #-} 
... 
interpret :: forall m. (Int -> m()) -> Elo a -> Int -> m a 
+0

にタイプ変数mを持参してくださいサンプルコードの次のステートメントの "ProgramViewはGADTなので、evalの型注釈は必須です。" – Duschvorhang

関連する問題