【问题标题】:Haskell record syntax desugared脱糖的 Haskell 记录语法
【发布时间】:2014-02-13 16:06:16
【问题描述】:

我了解如何在 Haskell 中使用记录语法,但我很难理解花括号 中的内容是什么

data PairRecord = PR {foo::Int, bar::String} deriving (Eq,Show)
x = (PR {foo=1, bar="init"})
y= x {foo=23}
  • 这个{foo=23} 是什么?最后一行看起来好像是 函数 x 的参数,显然不是这样。
  • 有吗 我可以用{foo=23} 做任何其他事情,除了把它放在后面 一个记录?
  • 有没有一种正式的方法可以像使用 do 符号那样对其进行脱糖?

【问题讨论】:

    标签: haskell


    【解决方案1】:

    这种语法称为“记录更新”或“使用字段标签更新”,在Section 3.15.3 of the Haskell 2010 report 中进行了描述。可以脱糖。确切的规则在报告中给出。在您的示例中,x {foo = 23} 的脱糖是

    case x of
      PR f b -> PR 23 b
      _      -> error "Update error"
    

    请注意,该报告在section before, 3.15.2, on "Construction using field labels" 中描述的脱糖中使用了一个名为“pick”的辅助函数。

    【讨论】:

    • 所以你可以对 x {foo=23} 脱糖,但是 {foo=23} 单独没有意义,唯一的用法是与它前面的 x(或其他记录)结合使用?
    • 是的,没错。 {foo = ...} 语法只能用于记录的构造、模式匹配或更新,并且只能与其他组件结合使用。它没有孤立的意义。
    【解决方案2】:

    通过查看类型:

    :t PR
    PR :: Int -> String -> PairRecord
    

    所以这意味着你需要一个 Int 和一个 String 来构造一个 PairRecord。

    现在,在 PairRecord 的定义中,您已经定义了访问器:

    :t foo
    foo :: PairRecord -> Int
    

    为了使用 foo(作为访问器),您需要提供一个 PairRecord。你得到一个 Int 作为返回值:

    foo y
    23
    

    这意味着单独的 foo 没有任何意义,这个函数需要一个 PairRecord。

    正如 kosmikus 已经指出的那样,语法

    y= x {foo=23}
    

    从现有的 PairRecord 创建 y,整数设置为 23(在访问器函数的帮助下)。

    【讨论】:

    • foo does 有一个明确的含义:它是一个从 PairRecord 到 Int 的函数。但是,如果 {foo=23} 前面没有 x,它就什么都不是。
    【解决方案3】:

    你需要的是lenses。但首先你必须安装包 lens。

    【讨论】:

    • 天哪,镜头会变成 Haskell 的 jQuery 吗?
    • 尽管我很喜欢镜头,但这并不能解决所问的问题。它可能是一个很好的旁注,但它不能回答问题。
    • @David Young:这不是旁注,这是一个“指南”。我想让他免于脱糖循环。
    • @Steven Dobay:我个人认为最好先学习基本概念,然后在这些概念的基础上学习技巧和更好的技术。这似乎是有人在询问如何进行加法并告诉他们只使用计算器(在这种情况下,是一个非常精细且可能令人生畏的计算器)。
    • @David Young:你是对的!我之前的某个人向他展示了基础知识(脱糖),然后我给了他镜片。这是他想要使用的选择。但首先,正如您所说,建议您进行基础练习。
    猜你喜欢
    • 2015-05-24
    • 2020-07-24
    • 2014-01-03
    • 1970-01-01
    • 2015-08-22
    • 2020-01-24
    • 2021-07-09
    • 2010-12-26
    • 1970-01-01
    相关资源
    最近更新 更多