Упорядочивание аргументы, как предполагает leftaroundabout, позволяет для определения опрятнее:
wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> f b) -> a -> f a
wfmap u w g = fmap w . g . u
Что касается библиотеки поддержки, объектив обеспечивает nifty support for isomorphisms. Немного более широко, как отмечает Gurkenglas ...
Functor f => (b -> f b) -> a -> f a
также называют Lens' a b
и является центральной частью библиотеки объектива.
Без погружения в детали того, как и почему это работает, одним из следствий является то, что ваша функция может быть определена как:
wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> f b) -> a -> f a
wfmap u w g = (iso u w) g
Или даже:
wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> f b) -> a -> f a
wfmap = iso
wfmap
просто (специализированная версия) iso
, которая выдает функцию, которая может быть использована для преобразования функции b -> f b
в «место назначения изоморфизма» на номер a -> f a
, расположенный на изоморфизм "источник".
Также стоит отметить mapping
, который может быть использован для несколько иной цели применения fmap
на другой стороне изоморфизма:
GHCi> :t \u w g -> over (mapping (iso u w)) (fmap g)
\u w g -> over (mapping (iso u w)) (fmap g)
:: Functor f => (s -> a) -> (b -> t) -> (a -> b) -> f s -> f t
GHCi> :t \u w g -> under (mapping (iso u w)) (fmap g)
\u w g -> under (mapping (iso u w)) (fmap g)
:: Functor f => (s -> a) -> (b -> a1) -> (a1 -> s) -> f b -> f a
Наконец, следует отметить, что iso u w
можно заменить любым Iso
вы может найти в библиотеках или предопределено в другом месте.
Разве не имеет смысла принимать 'x :: a' в качестве последнего аргумента? – leftaroundabout
@leftaroundabout, о да, это так. Спасибо что подметил это. Но это просто псевдокод, чтобы объяснить мою проблему. Просто, у меня есть много функций и типов, которые используют шаблон, подобный этому, и мне интересно, есть ли лучший способ сделать это. – iluvAS
Ваш 'wfmap' объявляет 5 аргументов в типе, но только 4 в определении. Я думаю, что у вас есть дополнительный аргумент типа 'a' в типе. – chepner