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) 我读了以下两个问题(第一个,第二个),并且我相信$
只能用于单态类型。但我同样认为.
也只能用于单态类型,因此将类似地失败。
为什么第一个代码可以成功编译,但第二个代码不能?(例如,GHC是否有适用于第一种情况的特殊规则,无法应用于第二个问题?)
2) 是否有当前的GHC扩展可以编译第二个代码? (可能ImpredicativePolymorphism在某些时候可以做到这一点,但它似乎已被弃用,有什么替代品吗?)
3) 有没有办法使用GHC扩展定义类似`my_dollar`
的东西,以执行$
的操作,但也能处理多态类型,以使(print . runST) `my_dollar` fourty_two
编译?
编辑:建议回答:
此外,以下内容无法编译:
main = ((.) print runST) fourty_two -- (5)
这与(1)相同,只是不使用中缀版本的.
。
因此,看起来GHC对于$
和.
都有特殊规则,但仅适用于它们的中缀版本。
( (print . runST) $ ) fourty_two
确实可以工作。 - bdonlan$
会有所不同,而不是为什么用.
替换第一个$
会有所不同。我的两个示例都使用(a . b)
格式,与其他问题不同。那个问题可以通过 GHC 的特殊类型规则来回答,但似乎在这里并不适用。 - Clinton