如何正确解包 `data` 中的 `data`?
How to correctly unwrap `data` inside `data`?
我正在尝试访问嵌套数据(在下面的示例中 Bar
内的 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
——就像Bar
一样,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
以下工作,使用辅助函数进行展开,但必须有更好的方法:
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
不起作用?
函数 fn2 和 fn3 不起作用,因为编译器不知道您指的是哪个记录字段(foo)。您必须按名称引用记录字段。
函数 fn4 是一个完美的解决方案(虽然你的命名很混乱,getY 实际上 returns 包装记录在 Foo 构造函数中,而不是 y 值)。
据我所知,fn5 是最短的可能解决方案。我个人更喜欢辅助函数(如您的第四个示例):
getY :: Foo -> Int
getY (Foo rec) = rec.y
fn6 :: Bar -> Int
fn6 (Bar { x, foo }) = x + getY foo
我正在尝试访问嵌套数据(在下面的示例中 Bar
内的 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
——就像Bar
一样,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
以下工作,使用辅助函数进行展开,但必须有更好的方法:
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
不起作用?
函数 fn2 和 fn3 不起作用,因为编译器不知道您指的是哪个记录字段(foo)。您必须按名称引用记录字段。
函数 fn4 是一个完美的解决方案(虽然你的命名很混乱,getY 实际上 returns 包装记录在 Foo 构造函数中,而不是 y 值)。
据我所知,fn5 是最短的可能解决方案。我个人更喜欢辅助函数(如您的第四个示例):
getY :: Foo -> Int
getY (Foo rec) = rec.y
fn6 :: Bar -> Int
fn6 (Bar { x, foo }) = x + getY foo