给出以下定义:
import Control.Monad.ST
import Data.STRef
fourty_two = do
x <- newSTRef (42::Int)
readSTRef x
在 GHC 下编译如下:
main = (print . runST) fourty_two -- (1)
但这并不:
main = (print . runST) $ fourty_two -- (2)
但随后作为bdonlan在评论中指出,这确实可以编译:
main = ((print . runST) $) fourty_two -- (3)
但是,这不能编译
main = (($) (print . runST)) fourty_two -- (4)
这似乎表明 (3) 仅由于中缀的特殊处理而编译$
但是,它仍然没有解释为什么(1)能够编译。
问题:
1)我已阅读以下两个问题(first https://stackoverflow.com/questions/9468963/runst-and-function-composition, second https://stackoverflow.com/questions/8343239/type-error-with-rank-2-types-and-function-composition),我被引导相信$
只能用单态类型实例化。但我同样会假设.
只能用单态类型实例化,因此同样会失败。
为什么第一个代码成功但第二个代码不成功? (例如,GHC 对于第一种情况是否有特殊规则,但不能适用于第二种情况?)
2)当前是否有编译第二个代码的 GHC 扩展? (也许命令式多态性 http://www.haskell.org/ghc/docs/6.10.1/html/users_guide/other-type-extensions.html#impredicative-polymorphism在某个时候这样做过,但它似乎已被弃用,有什么可以替代它吗?)
3)有什么方法可以定义说`my_dollar`
使用 GHC 扩展来做什么$
确实如此,但也能够处理多态类型,所以(print . runST) `my_dollar` fourty_two
编译?
编辑:建议答案:
另外,以下内容无法编译:
main = ((.) print runST) fourty_two -- (5)
这与 (1) 相同,只是不使用中缀版本.
.
因此,GHC 似乎对两者都有特殊规则$
and .
,但仅限于它们的中缀版本。