Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 为什么MonadTrans不转换整个类型?_Haskell - Fatal编程技术网

Haskell 为什么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

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
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
,给定一个monad
m
可以将值
ma
提升为值
(tm)a
。您修复的参数数量决定了您谈论的是transformer(未提供参数)、transformed monad(提供了一个参数-希望transformer执行操作的monad)还是monadic值(提供了两个参数)。

因为当您完全应用时,只剩下一个表示类型的表达式,但是你想说明关于类型函数的事情,在这种情况下是
(*->*)->(*->*)
,这是一种接受单子(
*->*
+定律)并产生单子的东西。该类的任何实例都是这样一个转换器
t
,给定一个monad
m
可以将值
ma
提升为值
(tm)a
。您修复的参数数量决定了您谈论的是transformer(未提供参数)、transformed monad(提供了一个参数-您希望transformer作用的monad)还是monadic值(提供了两个参数).

Haskell类中类型变量的类型是从类声明中如何使用这些变量推断出来的。这里,
t::(*->*)->*->*->*
因为它需要一些
m
a
应用于它才能成为一个类型(而
m::*->*
因为它需要
a
应用于它才能成为一个类型)。Haskell类中的类型变量是从这些变量在类声明中的使用方式推断出来的。这里,
t::(*->*)->*->*->*
因为它需要一些
m
a
应用于它才能成为一个类型(而
m::*->*
因为它需要
a
应用于它才能成为一个类型)。