Пакет streaming
предлагает функцию zipsWith
zipsWith
:: (Monad m, Functor h)
=> (forall x y. f x -> g y -> h (x, y))
-> Stream f m r -> Stream g m r -> Stream h m r
и немного более оптимизированная версия,
zipsWith'
:: Monad m
=> (forall x y p. (x -> y -> p) -> f x -> g y -> h p)
-> Stream f m r -> Stream g m r -> Stream h m r
Они могут быть легко адаптированы к FreeT
из free
пакета. Но этот пакет предлагает другую версию бесплатного трансформатора монады:
newtype FT f m a = FT
{ runFT
:: forall r.
(a -> m r)
-> (forall x. (x -> m r) -> f x -> m r)
-> m r }
Существует также третья (довольно простая) формулировка:
newtype FF f m a = FF
{ runFF
:: forall n. Monad n
=> (forall x. f x -> n x) -- A natural transformation
-> (forall x. m x -> n x) -- A monad morphism
-> n a }
Можно конвертировать назад и вперед между FreeT
и FT
или FF
, что предлагает косвенный способ реализовать zipsWith
и его родственников для FF
и FT
. Но это кажется довольно неудовлетворительным. Я ищу более прямое решение.
Проблема, похоже, связана с проблемой копирования списков с помощью сгибов. Это было рассмотрено в статье " Короткие складки с гиперфункциями", Launchbury et al, а также сообщение в блоге Donnacha Kidney. Ни один из них не очень прост, и я понятия не имею, как они могут быть адаптированы к контекстам FT
или FF
.
Поскольку я изучил эту проблему, я понял, что streaming
должна действительно предлагать более мощные версии. Простейшим было бы что-то вроде
zipsWith''
:: Monad m
=> (forall x y p. (x -> y -> p) -> f x -> g y -> h p)
-> Stream f m r -> Stream g m s -> Stream h m (Either r s)
но более мощный вариант будет включать остаток:
zipsWithRemains
:: Monad m
=> (forall x y p. (x -> y -> p) -> f x -> g y -> h p)
-> Stream f m r
-> Stream g m s
-> Stream h m (Either (r, Stream g m s)
(f (Stream f m r), s))
Я бы предположил, что zipsWith''
будет не сложнее, чем zipsWith'
, но zipsWithRemains
может стать более сложной задачей в контексте FT
или FF
, так как остаток, по-видимому, должен каким-то образом восстановиться.
Заметка
Поскольку раньше была некоторая путаница, позвольте мне упомянуть, что я не ищу помощь в написании zipsWithRemains
для Stream
или FreeT
; Я ищу помощь только с функциями FT
и FF
.