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



上下文

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

{-# 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,这是GHC9.2中的一个尚未稳定的实验功能。

    GHC用户指南的相关版本是这样说的:

    此时,当OverloadedRecordUpdate为时,必须启用RebindableSyntax,并且要求用户提供getField和setField的定义。我们预计这一限制将在未来的GHC版本中取消,该版本内置对setField的支持。

    默认的getField可以从GHC.Records导入,但setField当前不可用,因此您必须自己实现它。

    玩得开心!

编辑11/08:这个答案大部分不完整,部分不正确。看看我的另一个答案

正如@alias所解释的,如果启用RebindableSyntax,前奏曲将不会自动加载。GHC.Records也不会,它通常由记录语法扩展加载并需要。

您必须添加以下内容:

import Prelude
import GHC.GetRecords

相关内容

  • 没有找到相关文章

最新更新