Учитывая дифференцируемый тип, мы знаем, что его Zipper
является Comonad
. В ответ на это Дэн Бертон спросил: "Если вывод делает comonad, значит ли это, что интеграция делает монаду? Или это глупость?". Я хотел бы задать этот вопрос конкретному значению. Если тип дифференцируемый, обязательно ли это монада? Одна формулировка вопроса заключалась бы в том, чтобы спросить, учитывая следующие определения
data Zipper t a = Zipper { diff :: D t a, here :: a }
deriving instance Diff t => Functor (Zipper t)
class (Functor t, Functor (D t)) => Diff t where
type D t :: * -> *
up :: Zipper t a -> t a
down :: t a -> t (Zipper t a)
можем ли мы писать функции с сигнатурами, аналогичными
return :: (Diff t) => a -> t a
(>>=) :: (Diff t) => t a -> (a -> t b) -> t b
подчиняясь законы Монады.
В ответах на связанные вопросы были два успешных подхода к аналогичной проблеме получения экземпляров Comonad
для Zipper
. Первый подход заключался в расширении класса Diff
, чтобы включить двойное значение >>=
и использовать частичное дифференцирование. Второй подход заключался в требовании, чтобы тип был дважды или бесконечно дифференцируемым.