Почему в 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