Написание карты для этого преобразователя монад

У меня есть преобразователь монад:

newtype ChoiceT f m a = ChoiceT (forall x . f x -> m x) -> m a

Теперь я думаю, что это функтор категории Monads, и я хотел бы сделать карту для этого

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

Является ли этот преобразователь функтором категории Monads? Если это так, то как я ошибаюсь при реализации карты? Если нет, то какой контрпример?


person Éamonn Olive    schedule 24.02.2020    source источник
comment
Боковое примечание: если у вас есть функтор в категории монад, тип отображения морфизма будет (m a -> n a) -> ChoiceT f m a -> ChoiceT f n a - изменение a на b - это отдельное дело. (См. Также класс MFunctor .)   -  person duplode    schedule 25.02.2020
comment
@duplode Спасибо, мне показалось странным, что MonadTrans документы сделали это, но, оглядываясь назад, они этого не сделали. Я, должно быть, сделал ошибку при копировании. С учетом вашего исправления все становится более осмысленным.   -  person Éamonn Olive    schedule 25.02.2020
comment
Если бы это было (forall x. m x -> f x) -> m a, была бы некоторая надежда на то, что это функтор   -  person luqui    schedule 25.02.2020


Ответы (1)


Согласно стандартным правилам определения ко / контравариантности, «позиция является ковариантной, если она находится слева от четного числа стрелок, применяемых к ней». Изучая сигнатуру ChoiceT, мы видим, что параметр m встречается как в противоположных, так и в совпадающих позициях. Таким образом, ChoiceT инвариантен в m.

person moonGoose    schedule 24.02.2020