Почему в Control.Arrow нет экземпляра Functor для Kleisli?

Пытаясь ознакомиться с Control.Arrow, я заметил, что новый тип Kleisli, похоже, допускает экземпляр Functor, что-то вроде:

instance Monad m => Functor (Kleisli m a) where
    fmap f (Kleisli k) = Kleisli $ liftM f . k

Есть ли причина, по которой этот экземпляр не предоставляется? Существует ли он в каком-то пакете как экземпляр-сирота?

2 ответа

Решение

Каждая стрелка может быть превращена в действительный Functor определяя

fmap f a = a >>> arr f

Однако невозможно объявить Functor быть суперклассом Arrow из-за их разных видов (Functor потребности * -> * в то время как Arrow потребности * -> * -> *). Таким образом, каждая стрелка должна определять экземпляр отдельно.

Вы можете обернуть любую стрелку ArrowMonad, который затем дает Applicative экземпляр (и, следовательно, также Functor): instance Arrow a => Applicative (ArrowMonad a) where ...,

Я не вижу какой-либо конкретной причины, почему Kleisli не хватает Functor пример. Наиболее вероятным кажется то, что вам это не нужно. Если вы хотите использовать функторные (или аппликативные, или монадические) операции, вы делаете это на оригинальной монаде. Вы только заверните монаду в Kleisli когда вам нужен интерфейс стрелки.

ОБНОВИТЬ

в Control.Arrow уже определено:

(>>^) :: Arrow a => a b c -> (c -> d) -> a b d
(^<<) :: Arrow a => (c -> d) -> a b c -> a b d

ОБНОВЛЕНИЕ 2

Если вы хотите вставить Free Монада в Kleisli - это невозможно, Free имеет один дополнительный параметр f,

Так что вам нужно использовать Arrow Transformer или создать новый Arrow класс, как

class Arrow a => ArrowFunctor f a | a -> f where
    afmap :: a b (f c)

Стрелки пакета содержат несколько примеров, но не реализуют Free

Другие вопросы по тегам