Короче говоря
Я блуждаю, должен ли я думать об использовании contramap
, когда я пишу код, подобный (. f) . g
, где f
на практике выполняет предварительную обработку второго аргумента для g
.
Длинная история длиннее
Я опишу, как я придумал код, который заставил меня задуматься над вопросом в заголовке.
Изначально у меня было два входа, a1 :: In
и a2 :: In
, заключенных в пару (a1, a2) :: (In,In)
, и мне нужно было выполнить две взаимодействующие обработки этих входов. В частности, у меня была функция binOp :: In -> In -> Mid
для создания временного результата и функция fun :: Mid -> In -> In -> Out
для передачи входных и выходных данных binOp
.
Учитывая, что функция части получает входные данные и выходные данные другой функции выше, я думал об использовании функциональной монады, поэтому я придумал это,
finalFun = uncurry . fun =<< uncurry binOp
что не очень сложно прочитать: binOp
принимает входные данные как пару и передает свой вывод, а затем свои входные данные в fun
, который также принимает входные данные как пару.
Однако я заметил, что в реализации fun
я фактически использовал только сокращенную версию входных данных, т. е. у меня было определение, подобное fun a b c = fun' a (reduce b) (reduce c)
, поэтому я подумал, что вместо fun
я мог бы использовать fun'
вместе с reduce
в определении. finalFun
; я придумал
finalFun = (. both reduce) . uncurry . fun' =<< uncurry binOp
который гораздо труднее читать, особенно потому, что в нем, как мне кажется, неестественный порядок частей. Я мог только подумать об использовании более описательного имени, как в
finalFun = preReduce . uncurry . fun' =<< uncurry binOp
where preReduce = (. both reduce)
Поскольку preReduce
на самом деле предварительно обрабатывает 2-й и 3-й аргумент fun'
, я сомневался, подходит ли сейчас момент для использования contramap
.
contramap
, но другой вариант, который вы, возможно, захотите рассмотреть, этоfinalFun = curry $ fun' <$> uncurry binOp <*> (reduce.fst) <*> (reduce.snd)
. - person bradrn   schedule 21.02.2021dimap f g h == h . g . f
- person chepner   schedule 21.02.2021dimap f g h == g . h . f
- person duplode   schedule 21.02.2021f
первым или последним, потом я поленился и просто отбарабанил их в порядке справа налево. - person chepner   schedule 21.02.2021Contravariant
для функций...? - person Daniel Wagner   schedule 21.02.2021lmap
. - person duplode   schedule 21.02.2021