【问题标题】:Ocaml: How to "easy" map a list of records to a list of record.field?Ocaml:如何“轻松”将记录列表映射到record.field列表?
【发布时间】:2011-05-14 18:35:40
【问题描述】:

假设我有以下记录:

type t = {a:int}

为了从列表中选择字段 a 的值,我执行以下操作:

let x = [{a=1};{a=2}]
let y = List.map (fun t -> t.a) x

这对我来说有点“不干净”。作为比较,在 Haskell 中我会执行以下操作:

data T = T { a :: Int}  
x = [T {a = 1}, T {a = 2}]
y = map a x

有没有办法在 Ocaml 中编写类似的东西(可能使用外部库)? 如果不可能,有人可以解释为什么会出现这种限制吗?

【问题讨论】:

    标签: ocaml record


    【解决方案1】:

    如果您使用 Jane Street 的 fieldslib 库,可用于核心,那么您可以编写:

    type t = { a:int; b:int } with fields
    

    这给你ab作为t -> int类型的选择器函数

    它还为您提供了一个名为Fields 的子模块,其中包含所谓的一等字段,其中包括选择器、修改器,以及对于某些应用程序而言至关重要的字段的字符串名称.例如,这对于在验证函数中生成良好的错误消息非常有用。

    您还可以在整个记录上获得一些高阶函数,最有用的是折叠记录。

    【讨论】:

    • 谢谢!这似乎暴露了我想要的功能。太糟糕了,它不是标准发行版的一部分。
    【解决方案2】:

    与标准 ML 不同,Ocaml 没有一流的记录选择器。(source)

    至于为什么做不到,那只是设计上的选择而已。

    【讨论】:

      【解决方案3】:

      Haskell 为字段名称隐式创建选择器函数。 OCaml 不这样做。您可以在创建记录类型时手动定义它们,这相当于 Haskell 代码所做的。

      type t = {a:int, b:int}
      let a x = x.a
      let b x = x.b
      

      【讨论】:

      • 我知道我可以手动做到这一点。问题是我使用具有大量结构的现有代码。因此,定义所有访问器很麻烦。
      猜你喜欢
      • 2016-01-20
      • 2021-06-07
      • 2021-05-14
      • 2016-09-27
      • 1970-01-01
      • 1970-01-01
      • 2016-12-17
      • 2021-09-30
      • 1970-01-01
      相关资源
      最近更新 更多