Haskell 遇到非常简单的记录语法问题

标签 haskell record

虽然是Haskell新手,但之前用过记录。它们易于使用。但是现在,当我想从记录中提取一些数据时,出现了“发现漏洞”错误。违规代码是:

let theSchemaId =  _schemaId schema

记录是这样定义的:

data Schema = Schema
  { _schemaId         :: !SchemaId

   , [   other fields ... ]
  }

这对我来说似乎非常简单,类似于我以前使用过的记录。但是,在运行上面的代码行时,出现以下错误。所有进口都已到位。关于其原因的任何想法?

错误:

 src/master/haskell-service/src/Handler/Strategy/Components/View.hs:695:34: error:
    src/master/haskell-service/src/Handler/Strategy/Components/View.hs:695:34: error:
    • Found hole: _schemaId :: Schema -> SchemaId
      Or perhaps ‘_schemaId’ is mis-spelled, or not in scope
    • In the expression: _schemaId
      In the expression: _schemaId schema
      In a pattern binding: theSchemaId :: SchemaId = _schemaId schema
    • Relevant bindings include
        theSchemaId :: SchemaId

最佳答案

毫无疑问,您已经知道,Haskell 代码中无法识别的标识符会产生错误消息。例如程序:

foo = noSuchIdentifier 10

生成错误信息:

HolyFields.hs:5:7-22: error:
    Variable not in scope: noSuchIdentifier :: Integer -> t

以下划线开头的无法识别的标识符也会生成错误消息,但消息不同,因为标识符被视为 typed holes .例如程序:

bar = _underscoredIdentifier 10

生成错误信息:

HolyFields.hs:1:7-28: error:
    • Found hole: _underscoredIdentifier :: Integer -> t
      Where: ‘t’ is a rigid type variable bound by
               the inferred type of bar :: t
               at HolyFields.hs:1:1-31
      Or perhaps ‘_underscoredIdentifier’ is mis-spelled, or not in scope

但是,如果标识符是已知的,则是否以下划线开头都不会出错。以下程序编译正常:

_noProblem = (*2)
quux = _noProblem 10

碰巧命名字段的标识符的情况没有什么不同。

因此,您看到的问题是,即使您认为字段 _schemaId 在使用时在范围内,但事实并非如此。您可能忘记加载包含其定义的模块,或者模块有一个排除它的导出列表。

特别注意,如果您仅导出Schema,如下所示:

module MyModule (Schema) where
data Schema = ...

这不会导出Schema 的构造函数或字段函数。你需要改为写:

module MyModule (Schema(..)) where
data Schema = ...

为了让 _schemaId 在导入模块的范围内。

关于Haskell 遇到非常简单的记录语法问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63348438/

相关文章:

haskell - 在回合制 ascii 游戏中使用 FRP(尤其是响应式(Reactive)香蕉)是否有意义?

haskell - Haskell 中的类型系统

haskell - 这些一元表达式是否等价

postgresql - 从函数返回带有列定义的记录

Haskell 对值进行临时多态性,计算临时多态性列表的长度

performance - 使用 Haskell 在功能上将数据集相互比较一次

android - 致命异常:找不到音频记录器线程和文件异常

ios - AVCaptureFileOutputRecordingDelegate 不写入文件,Swift 2

android - 当通过音频采样的数据数量超过 AudioRecord 构造函数中设置的 "bufferSizeInBytes"时会发生什么?

perl - 可以连接两个使用不同输入记录分隔符的 Perl 脚本吗?