使用 RecordDotSyntax 更新记录会导致错误
Updating a record using RecordDotSyntax results in an error
上下文
如果我将以下内容加载到 ghc-9.2.1-alpha2 which has support for 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更新
如果我将以下内容添加为 alias 和 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.
编辑 11/08:此答案大部分不完整且部分不正确。看我的另一个回答。
如@alias 所述,如果启用 RebindableSyntax
,Prelude 将不会自动加载。 GHC.Records
也不会,通常由记录语法扩展加载和要求。
您必须添加:
import Prelude
import GHC.GetRecords
这里有两个问题。
您已启用 RebindableSyntax
。这允许您重新定义某些行为
通过在本地范围内定义某些函数,否则从 Prelude 导入。因此,RebindableSyntax
意味着 NoImplicitPrelude
。您需要手动导入 Prelude
,可选择隐藏要覆盖的函数。
import Prelude hiding (...)
您启用了 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
目前还没有,所以要自己实现。
玩得开心!
上下文
如果我将以下内容加载到 ghc-9.2.1-alpha2 which has support for 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更新
如果我将以下内容添加为 alias 和 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.
编辑 11/08:此答案大部分不完整且部分不正确。看我的另一个回答。
如@alias 所述,如果启用 RebindableSyntax
,Prelude 将不会自动加载。 GHC.Records
也不会,通常由记录语法扩展加载和要求。
您必须添加:
import Prelude
import GHC.GetRecords
这里有两个问题。
您已启用
RebindableSyntax
。这允许您重新定义某些行为 通过在本地范围内定义某些函数,否则从 Prelude 导入。因此,RebindableSyntax
意味着NoImplicitPrelude
。您需要手动导入Prelude
,可选择隐藏要覆盖的函数。import Prelude hiding (...)
您启用了
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
目前还没有,所以要自己实现。玩得开心!