Grz*_*ała 53 haskell function-composition
为什么这个类型检查:
runST $ return $ True
Run Code Online (Sandbox Code Playgroud)
虽然以下不是:
runST . return $ True
Run Code Online (Sandbox Code Playgroud)
GHCI抱怨:
Couldn't match expected type `forall s. ST s c0'
with actual type `m0 a0'
Expected type: a0 -> forall s. ST s c0
Actual type: a0 -> m0 a0
In the second argument of `(.)', namely `return'
In the expression: runST . return
Run Code Online (Sandbox Code Playgroud)
ham*_*mar 48
简短的回答是类型推断并不总是适用于更高级别的类型.在这种情况下,它无法推断类型(.),但它会检查我们是否添加了显式类型注释:
> :m + Control.Monad.ST
> :set -XRankNTypes
> :t (((.) :: ((forall s0. ST s0 a) -> a) -> (a -> forall s1. ST s1 a) -> a -> a) runST return) $ True
(((.) :: ((forall s0. ST s0 a) -> a) -> (a -> forall s1. ST s1 a) -> a -> a) runST return) $ True :: Bool
Run Code Online (Sandbox Code Playgroud)
如果我们($)用自己的版本替换,第一个示例也会出现同样的问题:
> let app f x = f x
> :t runST `app` (return `app` True)
<interactive>:1:14:
Couldn't match expected type `forall s. ST s t0'
with actual type `m0 t10'
Expected type: t10 -> forall s. ST s t0
Actual type: t10 -> m0 t10
In the first argument of `app', namely `return'
In the second argument of `app', namely `(return `app` True)'
Run Code Online (Sandbox Code Playgroud)
同样,这可以通过添加类型注释来解决:
> :t (app :: ((forall s0. ST s0 a) -> a) -> (forall s1. ST s1 a) -> a) runST (return `app` True)
(app :: ((forall s0. ST s0 a) -> a) -> (forall s1. ST s1 a) -> a) runST (return `app` True) :: Bool
Run Code Online (Sandbox Code Playgroud)
这里发生的是GHC 7中有一个特殊的输入规则,它只适用于标准($)运算符.Simon Peyton-Jones 在GHC用户邮件列表的回复中解释了这种行为:
这是可以处理不可预测类型的类型推断的激励示例.考虑以下类型
($):Run Code Online (Sandbox Code Playgroud)($) :: forall p q. (p -> q) -> p -> q在这个例子中,我们需要实例
p有(forall s. ST s a),这就是impredicative多态是指:用实例化一个多态类型的类型变量.可悲的是,我知道没有任何合理复杂的系统可以在没有帮助的情况下进行检查.有很多复杂的系统,我至少有两篇关于论文的共同作者,但他们都太过于复杂地生活在GHC中.我们确实有一个boxy类型的实现,但是在实现新的类型检查器时我把它拿出来了.没有人理解它.
但是,人们经常这么写
Run Code Online (Sandbox Code Playgroud)runST $ do ...在GHC 7中我实现了一个特殊的输入规则,仅用于中缀的使用
($).只需将其(f $ x)视为一种新的语法形式,具有明显的输入规则,然后就可以了.
你的第二个例子失败了,因为没有这样的规则(.).
Dan*_*ner 34
这种runST $ do { ... }模式是如此常见,而且它通常不会进行类型检查的事实是如此令人烦恼,GHC包含了一些ST特定的类型检查黑客以使其工作.那些黑客可能会在这里为($)版本而不是(.)版本.
| 归档时间: |
|
| 查看次数: |
3254 次 |
| 最近记录: |