teoria religion racionalismo principio obras monadas leibniz filosofia educatina conocimiento haskell monads zipper deriving

haskell - religion - principio de leibniz



Son todos los tipos diferenciables de las mónadas. (2)

Dado un tipo diferenciable , sabemos que su Zipper es un Comonad . En respuesta a esto, Dan Burton preguntó: "Si la derivación hace una coma, ¿significa eso que la integración hace una mónada? ¿O es una tontería?". Me gustaría darle a esta pregunta un significado específico. Si un tipo es diferenciable, ¿es necesariamente una mónada? Una formulación de la pregunta sería preguntar, dadas las siguientes definiciones

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)

¿Podemos escribir funciones con firmas similares a

return :: (Diff t) => a -> t a (>>=) :: (Diff t) => t a -> (a -> t b) -> t b

obedeciendo las leyes de la mónada .

En las respuestas a las preguntas vinculadas, hubo dos enfoques exitosos para un problema similar de derivar instancias de Comonad para la Zipper . El primer enfoque fue expandir la clase Diff para incluir el dual de >>= y usar la diferenciación parcial . El segundo enfoque era exigir que el tipo fuera dos o infinitamente diferenciable .


No podemos unsurprising derivar una Monad para algo similar si revertimos absolutamente todo. Nuestra declaración anterior y nuevas declaraciones se encuentran a continuación. No estoy completamente seguro de que la clase definida a continuación sea realmente integración, por lo que no me referiré explícitamente como tal.

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

Primero definiremos lo opuesto a una Zipper , una Unzipper . En lugar de un producto será una suma.

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

Un Unzipper es un Functor mientras D'' t sea ​​un Functor .

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

Si recordamos la clase 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)

La clase de cosas opuestas a ella, Diff'' , es la misma pero con cada instancia de Zipper reemplazada con Unzipper y el orden de las flechas -> invertidas.

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

Si utilizamos mi solución al problema anterior.

around :: (Diff t, Diff (D t)) => Zipper t a -> Zipper t (Zipper t a) around z@(Zipper d h) = Zipper ctx z where ctx = fmap (/z'' -> Zipper (up z'') (here z'')) (down d)

Podemos definir el inverso de esa función, que se join para la 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''

Esto nos permite escribir una instancia de Unzipper para Unzipper .

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

Esta instancia está en la misma línea que la instancia de Comonad para la Zipper .

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


No. Los data V a funtor void data V a son diferenciables, pero el return no se puede implementar para ellos.