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)
这样的多参数约束究竟意味着什么的信息。我不完全理解 e
和 m
如何在实例头 => MonadError e (ReaderT r m)
中协同工作。
这些多参数约束是如何工作的?谢谢!
本质上,像 Show a
这样的约束约束类型变量 a
来表示可显示的类型。你似乎明白这一点。
C a b
形式的约束约束了类型变量对 a
和 b
。直观上,这个约束意味着这些类型之间存在关系。
考虑这个虚构的 class
class C a b where
sum :: a -> b -> (Int, b)
直觉上,约束 C a b
意味着 a
和 b
可以 sum
混合在一起(按此顺序!),并且该总和的结果将成为一对 (Int, b)
.
在你的情况下,你正在处理
class Monad m => MonadError e m | m -> e where
throwError :: e -> m a
这里,MonadError e m
表示e
和m
之间的如下关系。
m
是一个 monad
e
是一种类型,对于任何 a
,我们可以将任何值 x :: e
转换为 throwError x :: m a
。直觉上,这是一个 "error" 类型,表示一些错误的性质,而 throwError
只是在 monad 中包含这样的值
- 给定
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)
我目前正在阅读论文 Monad Transformers Step by Step 作者:Martin Grabmüller。
论文中有一部分列出了以下实例声明:
instance (MonadError e m) => MonadError e (ReaderT r m) where...
我已经查看了所有内容,但我真的找不到任何关于像 (Foo a b)
这样的多参数约束究竟意味着什么的信息。我不完全理解 e
和 m
如何在实例头 => MonadError e (ReaderT r m)
中协同工作。
这些多参数约束是如何工作的?谢谢!
本质上,像 Show a
这样的约束约束类型变量 a
来表示可显示的类型。你似乎明白这一点。
C a b
形式的约束约束了类型变量对 a
和 b
。直观上,这个约束意味着这些类型之间存在关系。
考虑这个虚构的 class
class C a b where
sum :: a -> b -> (Int, b)
直觉上,约束 C a b
意味着 a
和 b
可以 sum
混合在一起(按此顺序!),并且该总和的结果将成为一对 (Int, b)
.
在你的情况下,你正在处理
class Monad m => MonadError e m | m -> e where
throwError :: e -> m a
这里,MonadError e m
表示e
和m
之间的如下关系。
m
是一个 monade
是一种类型,对于任何a
,我们可以将任何值x :: e
转换为throwError x :: m a
。直觉上,这是一个 "error" 类型,表示一些错误的性质,而throwError
只是在 monad 中包含这样的值
- 给定
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)