代码之家  ›  专栏  ›  技术社区  ›  0dB

如何在“数据”中正确展开“数据”?

  •  2
  • 0dB  · 技术社区  · 9 年前

    我正在尝试访问嵌套数据( Foo.y 在…内 Bar 在下面的示例中),但展开的直接方法 Foo 在…内 酒吧 想到的都不管用。但是如何正确地展开它呢?

    这里是我的数据:

    module Foo where
    
    import Prelude
    
    data Foo = Foo { y :: Int }
    
    data Bar = Bar { x   :: Int
                   , foo :: Foo }
    

    以下(当然)无法编译,错误是 Could not match type { y :: Int } with type Foo 就像 酒吧 , Foo公司 需要先展开:

    fn1 :: Bar -> Int
    fn1 (Bar { x, foo }) = x + foo.y
    

    所以我对下面的内容抱有希望,但唉,编译器说不行(括号中 Foo公司 构造函数没有帮助):

    fn2 :: Bar -> Int
    fn2 (Bar { x, Foo { y } }) = x + y
    
    fn3 :: Bar -> Int
    fn3 (Bar { x, Foo f }) = x + f.y
    

    下面的方法有效,使用helper函数进行展开,但必须有更好的方法:

    getY (Foo foo) = foo -- helper function
    
    fn4 :: Bar -> Int
    fn4 (Bar { x, foo }) = let foo2 = getY foo in
                           x + foo2.y
    

    那么,如何进行嵌套展开?

    [编辑]

    经过一两个小时的尝试,我想出了一个有效的方法:

    fn5 :: Bar -> Int
    fn5 (Bar { x, foo = (Foo f) }) = x + f.y
    

    这是惯用的做法吗?为什么不呢 fn2 fn3 工作

    1 回复  |  直到 9 年前
        1
  •  3
  •   shark.dp    9 年前

    功能 第2页 fn3 不工作,因为编译器不知道您引用的是哪个记录字段( foo公司 ). 您必须按名称引用记录字段。

    作用 fn4 是一个完美的解决方案(尽管你的命名很混乱, 获得 实际上返回 Foo公司 构造函数,而不是 y 值)。

    据我所知, 第5页 是最短的可能解决方案。我个人更喜欢助手函数(如第四个示例):

    getY :: Foo -> Int
    getY (Foo rec) = rec.y
    
    fn6 :: Bar -> Int
    fn6 (Bar { x, foo }) = x + getY foo