2014-12-03 2 views
18

Учитывая differentiable type, мы знаем, что its Zipper is a Comonad. В ответ на это Дэн Бертон спросил: «Если вывод делает comonad, значит ли это, что интеграция делает монаду? Или это глупость?». Я хотел бы задать этот вопрос конкретному значению. Если тип дифференцируемый, это обязательно монада? одна формулировка вопроса будет просить, учитывая следующие определенияВсе типы дифференциации Monads

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 

повинуясь Monad laws.

В ответах на связанные вопросы были два успешных подхода к аналогичной проблеме получения Comonad экземпляров для Zipper. Первый подход - expand the Diff class to include the dual of >>= and use partial differentiation. Второй подход - require that the type be twice or infinitely differentiable.

ответ

5

№ Функция пустоты data V a является дифференцируемой, но return не может быть реализован для нее.

+0

Таким образом, это демонстрирует, что «быть дифференцируемым» не гарантирует, что что-то может быть «результатом интеграции». Он правильно отвечает на вопрос Сирдека, но не особенно отвечает мне. (Я не прошу ответа, просто заметив.) Производная нуля равна нулю, но неопределенный интеграл нуля не обязательно равен нулю. Это произвольная константа. –

+0

@ DanBurton Если вы считаете, что 'Zipper' держит' D t' как производную, 'D t' является производной от' t', приводит к экземпляру 'Comonad' для' Zipper t'. Интеграция - это инверсия дифференцирования, поэтому 't' является интегралом от' D t'. Наличие производной совпадает с интегралом. Вот почему я сформулировал вопрос так, как я это сделал: 't' является/интегралом от' D t' приводит к экземпляру 'Monad' для' t'? – Cirdec

+0

@DanBurton Мы можем сделать экземпляр «Monad» для чего-то противоположного, см. Мой новый ответ. – Cirdec

2

Мы можем unsurprising получить Monad для чего-то подобного, если мы полностью отменим все. Ниже приведено наше предыдущее заявление и новые заявления. Я не совсем уверен, что класс, определенный ниже, фактически является интеграцией, поэтому я не буду ссылаться на него явно как таковой.

 
if D t is the derivative of t then the product of D t and the identity is a Comonad 
if D' t is the ???  of t then the sum  of D' t and the identity is a Monad 

Сначала мы определим оппозит Zipper, в Unzipper. Вместо продукта это будет сумма.

data Zipper t a = Zipper { diff :: D t a , here :: a } 
data Unzipper t a =   Unzip (D' t a) | There a 

An Unzipper является Functor тех пор, пока D' t является Functor.

instance (Functor (D' t)) => Functor (Unzipper t) where 
    fmap f (There x) = There (f x) 
    fmap f (Unzip u) = Unzip (fmap f u) 

Если вспомнить класс Diff

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) 

класс вещей напротив него, Diff', то же самое, но с каждым экземпляром Zipper заменен Unzipper и порядка -> стрелки перевернутого ,

class (Functor t, Functor (D' t)) => Diff' t where 
    type D' t :: * -> * 
    up' :: t a -> Unzipper t a 
    down' :: t (Unzipper t a) -> t a 

Если мы используем мой solution to the previous problem

around :: (Diff t, Diff (D t)) => Zipper t a -> Zipper t (Zipper t a) 
around [email protected](Zipper d h) = Zipper ctx z 
    where 
     ctx = fmap (\z' -> Zipper (up z') (here z')) (down d) 

мы можем определить обратную той функции, которая будет join для Monad.

inside :: (Diff' t, Diff' (D' t)) => Unzipper t (Unzipper t a) -> Unzipper t a 
inside (There x) = x 
inside (Unzip u) = Unzip . down' . fmap f $ u 
    where 
     f (There u') = There u' 
     f (Unzip u') = up' u' 

Это позволяет нам написать Monad экземпляр для Unzipper.

instance (Diff' t, Diff' (D' t)) => Monad (Unzipper t) where 
    return = There 
    -- join = inside 
    x >>= f = inside . fmap f $ x 

Этот экземпляр находится в том же ключе, что и Comonad например, для Zipper.

instance (Diff t, Diff (D t)) => Comonad (Zipper t) where 
    extract = here 
    duplicate = around 
+0

Мне любопытно, есть ли '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'свободная монада' 'Free f'. – Cirdec

+1

D '(FD f) a = f (UnZipper (FD f) a). вверх "легко, но я не уверен, что спуститься вниз. Кажется, что 'f' должен был быть монадой, чтобы объединить слои. Обратите внимание, что 'up '. down'' представляется эквивалентным 'wrap'. –

Смежные вопросы