Я бы обычно использовал сопоставление с образцом, тем более, что вы используете все аргументы конструктора и их не так много. Кроме того, в данном примере это не является проблемой, но необходимо учитывать следующее:
data Foo = A {a :: Int} | B {b :: String}
fun x = a x + 1
Если вы используете шаблон согласования, чтобы сделать работу по типу Foo, вы в безопасности; невозможно получить доступ к члену, которого не существует. Если вы используете функции доступа, с другой стороны, некоторые операции, такие как вызов fun (B "hi!")
, приведут к ошибке выполнения.
EDIT: в то время как, конечно, вполне возможно забыть сопоставить какой-либо конструктор, соответствие шаблонов делает довольно явным, что то, что происходит, зависит от того, какой конструктор используется (вы также можете сообщить компилятору обнаружить и предупредить вас о неполных шаблонах), тогда как использование функции больше намекает на то, что идет любой конструктор, ИМО.
Аксессуаров лучше всего сохранять в тех случаях, когда вы хотите получить только один или несколько аргументов конструктора (потенциально много), и вы знаете, что их можно безопасно использовать (нет риска использования аксессора на неправильном конструкторе, как и в примере.)
Просто для полноты: есть также другая форма поиска по шаблону с использованием полей записи: 'vecAddA (Vector {х = ух, у = уу, г = VZ}) (Vector {х = WX, у = wy, y = wz}) = ... ' – hvr