为部分应用的函数绑定 class 个实例
Bind class instance for partially applied functions
Prelude中Bind
class的定义是:
class Apply m <= Bind m where
bind :: forall a b. m a -> (a -> m b) -> m b
它可以被理解为一个函数,它接受两个个输入参数,一个单子上下文中的值(m a
)和一个函数(a -> m b
)并在 monadic 上下文中返回一个值 (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 -> ?? -> b
,而 x
将绑定到第二个 [=26] =].
我的推理是否正确?
Which is a function taking three parameters. How does that typecheck?
据我所知,在当前上下文中这个函数签名:
bind m f x = f (m x) x
应该等于:
bind m f = \x -> f (m x) x
为了补充 swizard 所说的(这是正确的),一种检查类型 class 函数的类型签名的方法是,一旦它被专门用于特定实例,就是将其写出来并查看如果 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 [...]
[...]
此外,以防万一您还不知道,函数类型构造函数 ->
是 right-associative,因此 a -> (r -> b)
与 a -> r -> b
相同。
Prelude中Bind
class的定义是:
class Apply m <= Bind m where
bind :: forall a b. m a -> (a -> m b) -> m b
它可以被理解为一个函数,它接受两个个输入参数,一个单子上下文中的值(m a
)和一个函数(a -> m b
)并在 monadic 上下文中返回一个值 (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 -> ?? -> b
,而 x
将绑定到第二个 [=26] =].
我的推理是否正确?
Which is a function taking three parameters. How does that typecheck?
据我所知,在当前上下文中这个函数签名:
bind m f x = f (m x) x
应该等于:
bind m f = \x -> f (m x) x
为了补充 swizard 所说的(这是正确的),一种检查类型 class 函数的类型签名的方法是,一旦它被专门用于特定实例,就是将其写出来并查看如果 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 [...]
[...]
此外,以防万一您还不知道,函数类型构造函数 ->
是 right-associative,因此 a -> (r -> b)
与 a -> r -> b
相同。