Haskell 为什么MonadTrans不转换整个类型?
MonadTrans类型定义如下:Haskell 为什么MonadTrans不转换整个类型?,haskell,Haskell,MonadTrans类型定义如下: class MonadTrans t where -- | Lift a computation from the argument monad -- to the constructed monad. lift :: (Monad m) => m a -> t m a 以及研究以下各项的实施情况: instance MonadTrans (ExceptT e) where lift = ExceptT . liftM Right
class MonadTrans t where
-- | Lift a computation from the argument monad
-- to the constructed monad.
lift :: (Monad m) => m a -> t m a
以及研究以下各项的实施情况:
instance MonadTrans (ExceptT e) where
lift = ExceptT . liftM Right
ExceptT
的类型构造函数有三个类型变量:
newtype ExceptT e m a =
ExceptT { runExceptT :: m (Either e a)) }
因此类型构造函数ExceptT
不能完全应用于类型。为什么这是可能的,更不用说
MonadTrans
的实例实现中的所有类型变量,除了e?首先要提到的是lift
定义使用“无点”样式。相当于
instance MonadTrans (ExceptT e) where
lift x = ExceptT (liftM Right x)
现在来回答问题。实例MonadTrans
下的表达式为(ExceptT e)
。这就是在类声明中取代t
的内容。让我们在lift
s签名中替换它:
instance MonadTrans (ExceptT e) where
-- (this was t)
-- ||
-- \/
lift :: (Monad m) => m a -> ExceptT e m a
lift = ExceptT (liftM Right x)
在这个表达式中,
liftM Right x::m(a b)
,这正是ExceptT
所采用的。首先要提到的是lift
定义使用了“无点”样式。相当于
instance MonadTrans (ExceptT e) where
lift x = ExceptT (liftM Right x)
现在来回答问题。实例MonadTrans
下的表达式是(e除外)
。这就是在类声明中取代t
的内容。让我们在lift
s签名中替换它:
instance MonadTrans (ExceptT e) where
-- (this was t)
-- ||
-- \/
lift :: (Monad m) => m a -> ExceptT e m a
lift = ExceptT (liftM Right x)
在这个表达式中,
liftM Right x::m(a b)
,这正是ExceptT
所采用的。因为当你完全应用时,你只剩下一个表示类型的表达式,但是你想陈述关于类型函数的事情,在这种情况下是(*->*)->(*->*)
,这是一种接受单子(*->*
+法则)并产生单子的东西。该类的任何实例都是这样一个转换器t
,给定一个monadm
可以将值ma
提升为值(tm)a
。您修复的参数数量决定了您谈论的是transformer(未提供参数)、transformed monad(提供了一个参数-希望transformer执行操作的monad)还是monadic值(提供了两个参数)。因为当您完全应用时,只剩下一个表示类型的表达式,但是你想说明关于类型函数的事情,在这种情况下是(*->*)->(*->*)
,这是一种接受单子(*->*
+定律)并产生单子的东西。该类的任何实例都是这样一个转换器t
,给定一个monadm
可以将值ma
提升为值(tm)a
。您修复的参数数量决定了您谈论的是transformer(未提供参数)、transformed monad(提供了一个参数-您希望transformer作用的monad)还是monadic值(提供了两个参数).Haskell类中类型变量的类型是从类声明中如何使用这些变量推断出来的。这里,t::(*->*)->*->*->*
因为它需要一些m
和a
应用于它才能成为一个类型(而m::*->*
因为它需要a
应用于它才能成为一个类型)。Haskell类中的类型变量是从这些变量在类声明中的使用方式推断出来的。这里,t::(*->*)->*->*->*
因为它需要一些m
和a
应用于它才能成为一个类型(而m::*->*
因为它需要a
应用于它才能成为一个类型)。