绑定部分应用函数的类实例

时间:2017-02-05 11:39:56

标签: monads purescript

Prelude中Bind类的定义是:

class Apply m <= Bind m where
  bind :: forall a b. m a -> (a -> m b) -> m b

它可以作为一个函数读取两个输入参数,monadic上下文中的值(m a)和函数(a -> m b)并返回一个值monadic context(m b)。

部分应用函数的Bind实例定义为:

instance bindFn :: Bind ((->) r) where
  bind m f x = f (m x) x

这是一个采用三个参数的函数。那个类型检查怎么样?

如果我尝试用更具体的类型替换m a,我会得到(如果我错了,请纠正我):

(((->) ??) a) -> (a -> (((->) ??) b)) -> (((->) ??) b)

相当于

(?? -> a) -> (a -> (?? -> b)) -> (?? -> b)

假设变量m绑定到(?? -> a),f将绑定到a -> ?? -> bx绑定到第二个??

我的推理是否正确?

2 个答案:

答案 0 :(得分:6)

  

这是一个带三个参数的函数。那个类型检查怎么样?

据我所知,在当前上下文中这个函数签名:

bind m f x = f (m x) x

应该等于:

bind m f = \x -> f (m x) x

答案 1 :(得分:3)

要添加到swizard所说的内容(这是正确的),一种方法来检查类型类函数的类型签名,一旦它专门用于特定实例,就是将其写出来并查看psci是否同意:

> :type bind :: forall r a b. (r -> a) -> (a -> r -> b) -> (r -> b)
forall r a b. (r -> a) -> (a -> r -> b) -> r -> b

所以你的推理确实是正确的。如果我们写出了错误的类型,我们就会遇到类型错误:

> :type bind :: forall r. r -> r
Error found:
[...]
   Could not match type [...] with [...]
[...]

另外,如果您还不知道,函数类型构造函数->是右关联的,因此a -> (r -> b)a -> r -> b相同。

相关问题