Написание карты для этого монад трансформера - PullRequest
1 голос
/ 24 февраля 2020

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

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 с? Если это так, как я ошибаюсь при реализации карты? Если это не то, что встречный пример есть?

1 Ответ

3 голосов
/ 25 февраля 2020

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

...