haskell 中的多参数上下文约束

Multi-parameter context constraints in haskell

我目前正在阅读论文 Monad Transformers Step by Step 作者:Martin Grabmüller。

论文中有一部分列出了以下实例声明:

instance (MonadError e m) => MonadError e (ReaderT r m) where...

我已经查看了所有内容,但我真的找不到任何关于像 (Foo a b) 这样的多参数约束究竟意味着什么的信息。我不完全理解 em 如何在实例头 => MonadError e (ReaderT r m) 中协同工作。

这些多参数约束是如何工作的?谢谢!

本质上,像 Show a 这样的约束约束类型变量 a 来表示可显示的类型。你似乎明白这一点。

C a b 形式的约束约束了类型变量对 ab。直观上,这个约束意味着这些类型之间存在关系。

考虑这个虚构的 class

class C a b where
   sum :: a -> b -> (Int, b)

直觉上,约束 C a b 意味着 ab 可以 sum 混合在一起(按此顺序!),并且该总和的结果将成为一对 (Int, b).

在你的情况下,你正在处理

class Monad m => MonadError e m | m -> e where
   throwError :: e -> m a

这里,MonadError e m表示em之间的如下关系。

  1. m 是一个 monad
  2. e 是一种类型,对于任何 a,我们可以将任何值 x :: e 转换为 throwError x :: m a。直觉上,这是一个 "error" 类型,表示一些错误的性质,而 throwError 只是在 monad
  3. 中包含这样的值
  4. 给定 m,只有一种错误类型 e。换句话说,关系实际上是一个函数。这通过上面 class 中的函数依赖性 ... | m -> e 来表达。

简单的版本是:MonadError m a 表示 m 是一个 monad,它可以表达一些 "error values",类型为 e

例如,如果我们有MonadError M String可用,我们可以写

foo :: Int -> M Int
foo n | n == 0    = throwError "can't handle zero!"
      | otherwise = return (100 `div` n)