haskell - 使用 RecordDotSyntax 更新记录会导致错误

标签 haskell ghc

上下文

如果我将以下内容加载到ghc-9.2.1-alpha2中支持 RecordDotSyntax :

{-# LANGUAGE OverloadedRecordDot, OverloadedRecordUpdate, DuplicateRecordFields #-}
----------------------------------------------------------------------
data Point = Point { x :: Double, y :: Double }

instance Show Point where
    show p = "Point { x = " ++ show p.x ++ ", y = " ++ show p.y ++ " }"

p = Point 10 20

然后我可以在 ghci 中运行以下命令:

ghci> p { x = 30 }
Point { x = 30.0, y = 20.0 }

太棒了,它正在工作!

问题

但是,如果我将以下内容添加到上面的测试文件中:

result =
    let
        a = Point 1 2
        b = a { x = 3 }
    in
        b

然后重新加载,我收到以下消息:

ghci> :r
[1 of 1] Compiling Main             ( /home/dharmatech/tmp/test-ghc-9.2.0.20210422/point-update-issue.hs, interpreted )

/home/dharmatech/tmp/test-ghc-9.2.0.20210422/point-update-issue.hs:13:13: error:
    RebindableSyntax is required if OverloadedRecordUpdate is enabled.
   |
13 |         b = a { x = 3 }
   |             ^^^^^^^^^^^
Failed, no modules loaded.

我尝试过的

如果我按照消息提示添加 RebindableSyntax ,我会收到更多如下错误:

/home/dharmatech/tmp/test-ghc-9.2.0.20210422/point-update-issue.hs:3:27: error:
    Not in scope: type constructor or class ‘Double’
  |
3 | data Point = Point { x :: Double, y :: Double }
  |

问题

有办法让它发挥作用吗?或者只是还没有实现?

更新 2021-08-10

如果我添加以下内容作为别名Ari建议:

import Prelude
import GHC.Records

我得到以下信息:

point-update-issue.hs:17:13: error:
    Not in scope: ‘setField’
    Perhaps you meant ‘getField’ (imported from GHC.Records)
   |
17 |         b = a { x = 3 }
   |             ^^^^^^^^^^^
Failed, no modules loaded.

最佳答案

这里有两个问题。

  1. 您已启用RebindableSyntax。这允许您重新定义某些行为 通过在本地范围内定义某些函数(否则从 Prelude 导入)。因此,RebindableSyntax 意味着 NoImplicitPrelude。您需要手动导入 Prelude,可以选择隐藏要覆盖的函数。

    import Prelude hiding (...)
    
  2. 您已启用 OverloadedRecordUpdate,这是 GHC 9.2 中的一项实验性功能,尚未稳定。

    相关版本GHC User's Guide有这样说:

    At this time, RebindableSyntax must be enabled when OverloadedRecordUpdate is and users are required to provide definitions for getField and setField. We anticipate this restriction to be lifted in a future release of GHC with builtin support for setField.

    默认的getField可以从GHC.Records导入,但是setField目前不可用,所以你必须自己实现。

    玩得开心!

关于haskell - 使用 RecordDotSyntax 更新记录会导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68707198/

相关文章:

haskell - 在 Haskell 类型签名中列为约束变量?

haskell - 带分隔符的秒差距置换解析器

haskell - 如何在haskell中替换表达式中的变量?

haskell - Haskell 中的 exp x 和类型签名

比较 Haskell 和 C 计算素数的速度

启用分析的 Haskell 重新安装基础

haskell - 使用 Data.Machine,您将如何描述一个以非确定性函数的结果为分支的计划?

haskell - Haskell 中的算术表达式求值

Haskell 存在量化详解

haskell - GHC 提示重叠的实例,而实际上它们不是