Я уверен, что это простое решение, но оно ускользает от меня, и я не могу найти прямой ответ.Обратный подъем на аппликативные функторы
Как правило, при применении liftA2
предполагая бинарную функцию уже снят один раз, подпись выглядит следующим образом:
liftA2' :: (Applicative f1, Applicative f)
=> (f a -> f b -> f c) -> f1 (f a) -> f1 (f b) -> f1 (f c)
Можно ли применить «обратный», например liftA2
, таких как:
inverseA2 :: (Applicative f, Applicative f1)
=> (f a -> f b -> f c) -> f (f1 a) -> f (f1 b) -> f (f1 c)
в качестве конкретного примера, я хотел бы получить функцию:
f :: ([a] -> [b] -> [c]) -> [Maybe a] -> [Maybe b] -> [Maybe c]
Одним из способов было бы прибегнуть к «упаковке» каждый аргумент [Maybe a] -> Maybe [a]
и «распаковывать» Maybe [a] -> [Maybe a]
результат применения нормального liftA2
. Я хотел бы избежать этого, поскольку, как вы можете себе представить, упаковка разрушительна (например, pack [Just 1, Nothing, Just 2] == Nothing
).
Update:, как @ user2407038 отметил, для того, чтобы f
применить данную функцию, обязательно нужна функция вдоль линий [Maybe a] -> [a]
которые делает потерять информацию. Таким образом, для этих двух конкретных функторов нет очевидного способа удовлетворить дополнительное требование. Но для любых других двух функторов f
, f1
, которые имеют обратимую функцию forall a . f a -> f1 a
, принятый ответ идеально подходит для решения этого вопроса.
Возьмите 'f :: [Int] -> [Char] -> [Int]; f x y = [длина x + длина y] '. Что бы вы ожидали от 'inverseA2 f :: [Maybe Int] -> [Maybe Char] -> [Maybe Int]'? Что относительно 'f x y = [длина x + длина y, head x]'? Я не уверен, что общее определение будет ... – chi
Чтобы 'f' применял данную функцию, она должна вызывать' [a] 'из' [Maybe a] '(естественно, нет способа чтобы получить '[a]' из '[Maybe b]', поскольку нет способа получить 'a' из' b'), и поэтому вы обязательно * нуждаетесь в * функции '[Maybe a] -> [a]' - и, как вы заметили, эта функция обязательно теряет информацию. То же самое относится к общему случаю - существует несколько функторов 'f1, f2', которые имеют обратимую функцию' forall a. f1 a -> f2 a'. – user2407038
@ user2407038, поэтому была причина, по которой я не нашел прямого ответа, так как я искал неправильную проблему. Спасибо, что указали обратимые функции! Я буду больше смотреть на это. –