У меня есть тип данных с большим количеством полей:
data ManyFields a b c d .. = MF { f1 :: a, f2 :: b, f3 :: c .. }
Проблема 1
Как сопоставить функцию на каждом поле, избегая при этом реализации функции map
для каждого из них.
Например, это выглядит очень утомительно и неидиоматично:
-- | Note I am explicitly constructing ManyField after mapping a function onto the field
-- | This looks bad
mapf1 :: (a -> a1) -> ManyFields a b c .. -> ManyFields a1 b c ..
mapf1 g mf = MF (g . f1 $ mf) (f2 mf) ..
-- | Repeat for each field
mapf2 :: (b -> b1) -> ManyFields a b c .. -> ManyFields a b1 c ...
Я думаю, что какая-то функция более высокого порядка, абстрагирующая шаблон constructor . (mapfunction f)
, сократит шаблон, но есть ли лучшее решение?
Проблема вторая
Если я хочу заархивировать много ManyFields вместе и сопоставить функцию произвольной arity на каждом поле, похоже ли это, что это может быть экземпляр некоторого класса типа?
Случай использования:
(==) `mapFunction` mf1 `pairWiseZipField` mf2
Это выглядит как аппликативный для меня, но опять же я не уверен, как реализовать fmap
для этого типа.