Я пытаюсь получить доступ к вложенным данным (внутри Bar
в примере ниже), но простые подходы к разворачиванию Foo
внутри Bar
, которые приходят на ум, не работают. Но как развернуть его правильно?Как правильно разворачивать `данные` внутри` data`?
Вот мои данные:
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
Итак, как же я вложенный «разворачивать»?
[EDIT]
Через час или два в попытке вещи, я придумал это, который работает:
fn5 :: Bar -> Int
fn5 (Bar { x, foo = (Foo f) }) = x + f.y
Это идиоматических способ сделать это? Почему не работают fn2
и fn3
?
ОК, имеет смысл: это не _position_, а _NAME_ - просто щелкнул для меня, спасибо. И таким образом мой 'getY' следует называть' getFoo' или писать так, как вы его написали. FWIW, я не искал кратчайшего решения, кроме одного, где я вижу разрушение в шаблоне. Теперь, как я могу получить «y» прямо из шаблона? – 0dB
Нравится это: fn7 (Bar {x, foo = Foo {y}}) = x + y –
Также обратите внимание, что {поле} является синтаксическим сахаром для {field: field}. –