我想寫類似以下的東西:
newtype FooT c d m a = FooT { unFooT :: (c (d m)) a }
instance (MonadTrans c, MonadTrans d) => MonadTrans (FooT c d) where
lift = FooT . lift . lift
但是,此代碼段不會編譯:
Could not deduce (Monad (d m)) arising from a use of ‘lift’
我明白為什么這不會編譯;我們不知道任意轉換d m器的應用本身就是一個單子。但是,我不確定最好的方法。有沒有一種干凈的方法來制作這樣的東西?Monad (d m)如果我可以在實體宣告的左側添加一個約束,大概會通過,但我不知道該怎么做,因為m沒有系結。
uj5u.com熱心網友回復:
使用QuantifiedConstraintsGHC 擴展,這是
{-# LANGUAGE QuantifiedConstraints #-}
instance (MonadTrans c, MonadTrans d, forall m. Monad m => Monad (d m)) =>
MonadTrans (FooT c d) where
lift = FooT . lift . lift
min 約束與min不同lift。量化的約束僅僅意味著它所說的(“對于任何m :: Type -> Type,如果Monad m需要Monad (d m)”),并且在lift那個通用陳述句中被實體化,特定m 的被作為引數傳遞給lift. 因此lift'm并沒有逃脫它的范圍。
uj5u.com熱心網友回復:
從變形金剛 0.6開始,MonadTrans型別類就要求它保留Monad.
這意味著 的定義MonadTrans是:
type Lifting cls trans = forall m. cls m => cls (trans m)
class Lifting Monad trans => MonadTrans trans where
lift :: Monad m => m ~> trans m
ComposeT您呼叫的轉換器 ( ) 的組成FooT不需要指定提升,因此您在問題中提供的代碼應該適用于0.6 版本。
ComposeT已經存在于派生反式中
newtype Ok m a = Ok (Int -> Bool -> m a)
deriving
( Functor, Applicative, Alternative, Contravariant
, Monad, MonadPlus, MonadCont, MonadIO, MonadFix,
, MonadFail, MonadZip
)
via ReaderT Int (ReaderT Bool m)
deriving MonadTrans
via ComposeT (ReaderT Int) (ReaderT Bool)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/459670.html
