runST和函数组成

为什么这个types检查:

runST $ return $ True 

虽然以下不:

 runST . return $ True 

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 

3 Solutions collect form web for “runST和函数组成”

简而言之,types推断并不总是适用于更高级的types。 在这种情况下,它不能推断(.)的types,但是它会检查是否添加显式types注释:

 > :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 

如果我们用自己的版本replace($) ,第一个例子也会出现同样的问题:

 > let app fx = fx > :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)' 

再次,这可以通过添加types注释来解决:

 > :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 

这里发生的是GHC 7中有一个特殊的input规则,它只适用于标准($)操作符。 Simon Peyton-Jones 在GHC用户邮件列表的答复中解释了这种行为:

这是types推断的一个激励范例,可以处理impandicativetypes。 考虑($)的types:

 ($) :: forall p q. (p -> q) -> p -> q 

在这个例子中,我们需要实例化(forall s. ST sa) s。ST (forall s. ST sa) ,这就是impressiveic polymorphism的意思:实例化一个具有多态types的typesvariables。

可悲的是,我知道没有合理的复杂性系统可以单独检查[this]。 有很多复杂的系统,我至less在两篇文章上合作过,但都过于复杂,生活在GHC中。 我们确实有一个boxytypes的实现,但是在实现新的types检查器时我拿出来了。 没有人明白这一点。

但是,人们经常写作

 runST $ do ... 

在GHC 7中,我实现了一个特殊的input规则,仅用于($)缀使用。 只要把(f $ x)看作一种新的语法forms,用明显的键入规则就可以了。

你的第二个例子失败,因为(.)没有这样的规则。

runST $ do { ... }模式非常常见,而且通常不会进行types检查的事实非常令人讨厌,所以GHC包含了一些ST特定的types检查黑客来使其工作。 这些黑客可能在这里为($)版本,但不是(.)版本。

这些信息有点混乱(或者我觉得)。 让我重写你的代码:

 runST (return True) -- return True is ST s Bool (runST . return) True -- cannot work 

另一种说法是单态m0 a0 (返回的结果,如果得到a0)不能与(s.ST sa)统一。

  • Rust和Haskell的types类的特性有什么区别?
  • Haskell:怎么发音?
  • 了解GHCi让绑定的不同行为
  • 为什么我们需要monads?
  • 哈斯克尔:什么是弱头范式?
  • 在列表monad中使用return和not使用return
  • mtl,变形金刚,monads-fd,monadLib以及select的悖论
  • Haskell中的monadic IO构造只是一个约定吗?
  • 为什么没有关于Haskell(与Scala或C#相对)的协变和反变化的讨论?
  • 有趣的重复的fmap
  • Haskell函数组成(。)和函数应用($)成语:正确使用