gpt4 book ai didi

Haskell rank 2 多态性编译错误

转载 作者:行者123 更新时间:2023-12-03 14:21:44 24 4
gpt4 key购买 nike

给定以下定义:

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) 我已经阅读了以下两个问题( firstsecond ),我被引导相信 $只能用单态类型实例化。但我同样会假设 .只能用单态类型实例化,因此同样会失败。
为什么第一个代码成功但第二个代码没有? (例如,GHC 是否有针对第一种情况的特殊规则,它不能在第二种情况下适用?)

2) 是否有编译第二个代码的当前 GHC 扩展? (也许 ImpredicativePolymorphism 在某些时候这样做过,但似乎已被弃用,有什么替代它的吗?)

3) 有什么方法可以定义 `my_dollar`使用 GHC 扩展来做什么 $可以,但也能够处理多态类型,所以 (print . runST) `my_dollar` fourty_two编译?

编辑:建议答案:

此外,以下无法编译:
main = ((.) print runST) fourty_two -- (5)

这与 (1) 相同,只是不使用 . 的中缀版本。 .

因此,GHC 似乎对 $ 都有特殊的规则。和 . ,但只有它们的中缀版本。

最佳答案

  • 我不确定我理解为什么第二个不起作用。我们可以查看print . runST的类型并观察它是足够多态的,所以责任不在于 (.) .我怀疑 GHC 对中缀 ($) 的特殊规则只是还不够。如果您将此片段作为他们跟踪器上的错误提出,SPJ 和 friend 可能会重新检查它。

    至于为什么第三个示例有效,那只是因为 ((print . runST) $) 的类型再次出现。是足够多态的;实际上,它等于 print . runST 的类型.
  • 什么都没有取代ImpredicativePolymorphism ,因为 GHC 人员还没有看到任何用例,其中额外的程序员便利性超过了编译器错误的额外潜力。 (我认为他们也不会认为这是令人信服的,尽管我当然不是权威。)
  • 我们可以定义一个稍微不那么多态的 ($$) :
    {-# LANGUAGE RankNTypes #-}
    infixl 0 $$
    ($$) :: ((forall s. f s a) -> b) -> ((forall s. f s a) -> b)
    f $$ x = f x

    然后您的示例类型检查可以使用这个新运算符:
    *Main> (print . runST) $$ fourty_two
    42
  • 关于Haskell rank 2 多态性编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10345809/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com