7

私はHooplライブラリを使用しており、書き換え中に何らかの状態を保持したいと考えています。State書き換え関数は、使用されるモナドに関してポリモーフィックですが、モナドをライブラリのモナドの 1 つと組み合わせる方法がわかりませんFuel

以下は最小限の例です。MyMonadHooplCheckingFuelMonadとフラグを持つStateモナドを組み合わせたシノニムです。Stmt私の中間言語の単なるプレースホルダーであり、それほど重要ではありません.

{-# LANGUAGE GADTs, RankNTypes #-}

import Compiler.Hoopl
import Control.Monad.State

type MyMonad = CheckingFuelMonad (State Bool)

data Stmt e x where
  Bind :: () -> Stmt O O

rewriter :: forall e x. Stmt e x -> Fact x () -> MyMonad (Maybe (Graph Stmt e x))
rewriter (Bind ()) () = return $ do
  f <- get
  if f 
   then return $ Just emptyGraph
   else return Nothing

しかし、これはコンパイルされません -- GHCrewriteは間違った型を持っていると文句を言います:

Couldn't match expected type `Graph' Block Stmt e x'
       against inferred type `Maybe (g n O O)'
  Expected type: CheckingFuelMonad
                   (State Bool) (Maybe (Graph Stmt e x))
  Inferred type: CheckingFuelMonad
                   (State Bool) (Maybe (Maybe (g n O O)))

私がやりたいことは可能ですか?rewrite関数を正しく記述するにはどうすればよいですか?

4

2 に答える 2

4

hoopl コードをブラウズすると、CheckingFuelMonad が MonadTrans のインスタンスではないことがわかります。コンストラクターがエクスポートされていないため、MonadTrans を作成することはできません。ただし、次のように CheckingFuelMonad を StateT でラップすることもできます。

{-# LANGUAGE GADTs, RankNTypes #-}

import Compiler.Hoopl
import Control.Monad.State

type MyMonad = StateT Bool SimpleFuelMonad

data Stmt e x where
  Bind :: () -> Stmt O O

rewriter :: forall e x. Stmt e x -> Fact x () -> MyMonad (Maybe (Graph Stmt e x))
rewriter (Bind ()) () = do
  f <- get
  if f
   then return $ Just emptyGraph
   else return Nothing
于 2011-06-27T16:24:43.027 に答える
1

さて、現在のエラーの直接の原因は単純です。fが真の場合、最終的な式は何ですか? これを取ると:

rewriter :: forall e x. Stmt e x -> Fact x () -> MyMonad (Maybe (Graph Stmt e x))
rewriter (Bind ()) () = return $ do
  f <- get
  if f 
   then return $ Just emptyGraph
   else return Nothing

True...そして、取得したブランチ以外をすべて削除します。

rewriter :: forall e x. Stmt e x -> Fact x () -> MyMonad (Maybe (Graph Stmt e x))
rewriter (Bind ()) () = return $ do
  return $ Just emptyGraph

...これは次のように単純化されます。

rewriter :: forall e x. Stmt e x -> Fact x () -> MyMonad (Maybe (Graph Stmt e x))
rewriter (Bind ()) () = return $ return $ Just emptyGraph

の種類はreturn $ return $ Just emptyGraph何ですか?

(Monad m1, Monad m2, GraphRep g) => m1 (m2 (Maybe (g n O O)))

言い換えれば、あなたはreturnそこに余分なものを持っています. はモナド変換子として定義されていないように見えますが、(Monad m) => CheckingFuelMonad mそれ自体はです。したがって、モナド層は 1 つしかありません。MonadCheckingFuelMonadreturn

于 2011-06-27T16:29:06.193 に答える