У меня есть монадный преобразователь:
newtype ChoiceT f m a = ChoiceT (forall x . f x -> m x) -> m a
Теперь я думаю, что это функтор для категории Monad
с, и я хотел бы сделать карту для этого
mapChoiceT ::
(n b -> m a)
-- ^ Function from one monad to another.
-- This is our morphism in the domain.
-> (ChoiceT f m a -> ChoiceT f n b)
-- ^ Function from lifted versions of the monads.
-- This is our morphism in the image
Однако реализация этого ускользает от меня. Мне удалось написать более простую версию, в которой n ~ m
:
lift2 ::
(m a -> m b)
-> (ChoiceT f m a -> ChoiceT f m b)
lift2 f m = ChoiceT (\ chooser -> f $ runChoiceT chooser m)
where
runChoiceT :: (forall x . f x -> m x) -> ChoiceT f m a -> m a
runChoiceT chooser (ChoiceT runner) = runner chooser
Но абстрагирование от этого кажется мне не под силу. Оказалось, что это может быть контравариантный функтор, что, безусловно, затруднит написание ковариантной карты, но мне не повезло и написать contramapChoiceT
.
mapChoiceT ::
(n b -> m a)
-- ^ Function from one monad to another.
-- This is our morphism in the domain.
-> (ChoiceT f m a -> ChoiceT f n b)
-- ^ Function from lifted versions of the monads.
-- This is our morphism in the image
Является ли этот преобразователь Функтор на категорию Monad
с? Если это так, как я ошибаюсь при реализации карты? Если это не то, что встречный пример есть?