で等式推論を破るI、そのまま運用パッケージドゥGADTsはHaskellの
{-# LANGUAGE GADTs #-}
import Control.Monad ((<=<))
import Control.Monad.Operational
data Motor' a where
--Define GADT
serialNewportT :: (Monad m, MonadIO m) => ProgramT Motor' m a -> m a
serialNewportT = eval <=< viewT
where
eval :: (Monad m, MonadIO m) => ProgramViewT Motor' m v -> m v
eval (Return x) = return x
eval (x :>>= k) = f x >>= serialNewportT . k
f :: (Monad m, MonadIO m) => Motor' a -> m a
f = undefined -- excluded for brevity
コードからProgramTを使用して、以下のインタプリタは、現在、うまくチェックを入力しています。しかし、私はインタープリタが異なるモーターをどのように扱うかを切り換えたいので、f
をハードコードではなくパラメータにしたいと思っています。次のコードでこのスイッチを作ろうとしました。
{-# LANGUAGE GADTs #-}
import Control.Monad ((<=<))
import Control.Monad.Operational
data Motor' a where
--Define GADT
serialNewportT :: (Monad m, MonadIO m) => (Motor' a -> m a) -> ProgramT Motor' m a -> m a
serialNewportT f = eval <=< viewT
where
eval :: (Monad m, MonadIO m) => ProgramViewT Motor' m v -> m v
eval (Return x) = return x
eval (x :>>= k) = f x >>= serialNewportT f . k
私はちょうど同じタイプのローカル1でグローバル名を交換していますので
しかし、このコードは、エラーメッセージ
Couldn't match type ‘b’ with ‘c’
‘b’ is a rigid type variable bound by
a pattern with constructor
:>>= :: forall (instr :: * -> *) (m :: * -> *) a b.
instr b -> (b -> ProgramT instr m a) -> ProgramViewT instr m a,
in an equation for ‘eval’
‘c’ is a rigid type variable bound by
the type signature for
serialNewportT :: (Monad m, MonadIO m) =>
(Motor' c -> m c) -> ProgramT Motor' m a -> m a
Expected type: Motor' c
Actual type: Motor' b
で失敗し、私はそれが滞りなく働いているべきであると考えているだろう。パラメータとしてf
を使用して統一する型を取得するにはどうすればよいですか?
:
は、あなただけの上位タイプを必要としています。元のコードでは、任意の 'a '型に対して' Motor' a'型でインスタンス化することができますが、非動作型コードでは 'ProgramT Motor 'ma'と全く同じ型です一方、関数本体では、他の(存在する場合は量子化された)型 'b'に対して' Motor 'b''で 'f'を呼び出します。 'serialNewportT ::(Monad m、MonadIO m)=>(forall xモーター 'x - > mx) - > Programmotモーター' ma - > ma' – user2407038
@ user2407038は答えのようです私には – Carsten
ええ。スコープ付きの型変数を調べて、すべてを一致させようとしましたが、ランクN型は見ていませんでした。私はそれが最終的にそれらを学ぶ時だと思います。 @ user2407038、これを回答したい場合は、そのクレジットをお渡しします。 – user640078