He escuchado el término "coalgebras" varias veces en la programación funcional y los círculos PLT, especialmente cuando la discusión es sobre objetos, comonads, lentes y demás. Buscar en Google este término ofrece páginas que ofrecen una descripción matemática de estas estructuras, lo cual me resulta bastante incomprensible. ¿Alguien puede explicar qué significan las coalgebras en el contexto de la programación, cuál es su importancia y cómo se relacionan con los objetos y los comonads?
scala
haskell
functional-programming
category-theory
recursion-schemes
missingfaktor
fuente
fuente
Respuestas:
Álgebras
Creo que el lugar para comenzar sería entender la idea de un álgebra . Esto es solo una generalización de estructuras algebraicas como grupos, anillos, monoides, etc. La mayoría de las veces, estas cosas se introducen en términos de conjuntos, pero como estamos entre amigos, hablaré sobre los tipos de Haskell. (Sin embargo, no puedo resistirme a usar algunas letras griegas, ¡hacen que todo se vea mejor!)
Un álgebra, entonces, es solo un tipo
τ
con algunas funciones e identidades. Estas funciones toman diferentes números de argumentos de tipoτ
y producen unτ
: no cursivo, todos parecen(τ, τ,…, τ) → τ
. También pueden tener "identidades", elementosτ
que tienen un comportamiento especial con algunas de las funciones.El ejemplo más simple de esto es el monoide. Un monoide es cualquier tipo
τ
con una funciónmappend ∷ (τ, τ) → τ
y una identidadmzero ∷ τ
. Otros ejemplos incluyen cosas como grupos (que son como monoides, excepto con unainvert ∷ τ → τ
función adicional ), anillos, celosías, etc.Todas las funciones funcionan
τ
pero pueden tener aridades diferentes. Podemos escribir esto comoτⁿ → τ
, donde seτⁿ
asigna a una tupla den
τ
. De esta manera, tiene sentido pensar en las identidades comoτ⁰ → τ
dóndeτ⁰
está solo la tupla vacía()
. Así que podemos simplificar la idea de un álgebra ahora: es solo un tipo con algunas funciones.Un álgebra es solo un patrón común en matemáticas que se ha "factorizado", tal como lo hacemos con el código. La gente notó que un montón de cosas interesantes —los monoides, grupos, celosías, etc. mencionados anteriormente— siguen un patrón similar, por lo que lo resumieron. La ventaja de hacer esto es la misma que en la programación: crea pruebas reutilizables y facilita ciertos tipos de razonamiento.
Álgebras F
Sin embargo, no hemos terminado con el factoring. Hasta ahora, tenemos un montón de funciones
τⁿ → τ
. De hecho, podemos hacer un buen truco para combinarlos en una sola función. En particular, echemos un vistazo a los monoides: tenemosmappend ∷ (τ, τ) → τ
ymempty ∷ () → τ
. Podemos convertirlos en una sola función usando un tipo de suma—Either
. Se vería así:De hecho, podemos usar esta transformación repetidamente para combinar todas las
τⁿ → τ
funciones en una sola, para cualquier álgebra. (De hecho, podemos hacer esto para cualquier número de funcionesa → τ
,b → τ
y así sucesivamente para cualquieraa, b,…
).Esto nos permite hablar sobre álgebras como un tipo
τ
con una sola función desde un lío deEither
s a un soloτ
. Para monoides, este desastre es:Either (τ, τ) ()
; para los grupos (que tienen un extra deτ → τ
funcionamiento), es:Either (Either (τ, τ) τ) ()
. Es un tipo diferente para cada estructura diferente. Entonces, ¿qué tienen en común todos estos tipos? Lo más obvio es que todos son solo sumas de productos: tipos de datos algebraicos. Por ejemplo, para monoides, podríamos crear un tipo de argumento monoide que funcione para cualquier monoide τ:Podemos hacer lo mismo para grupos, anillos, celosías y todas las demás estructuras posibles.
¿Qué más hay de especial en todos estos tipos? ¡Pues todos lo son
Functors
! P.ej:Entonces podemos generalizar nuestra idea de un álgebra aún más. Es solo un tipo
τ
con una funciónf τ → τ
para algún functorf
. De hecho, podríamos escribir esto como una clase de tipo:Esto a menudo se denomina "álgebra F" porque lo determina el functor
F
. Si pudiéramos aplicar parcialmente las clases de tipos, podríamos definir algo asíclass Monoid = Algebra MonoidArgument
.Coalgebras
Ahora, espero que comprenda bien qué es un álgebra y cómo es solo una generalización de las estructuras algebraicas normales. Entonces, ¿qué es un F-coalgebra? Bueno, el co implica que es el "dual" de un álgebra, es decir, tomamos un álgebra y volteamos algunas flechas. Solo veo una flecha en la definición anterior, así que solo voltearé eso:
¡Y eso es todo! Ahora, esta conclusión puede parecer un poco frívola (je). Le dice qué es un coalgebra, pero en realidad no da una idea de cómo es útil o por qué nos importa. Llegaré a eso en un momento, una vez que encuentre o encuentre un buen ejemplo o dos: P.
Clases y objetos
Después de leer un poco, creo que tengo una buena idea de cómo usar coalgebras para representar clases y objetos. Tenemos un tipo
C
que contiene todos los posibles estados internos de los objetos en la clase; la clase en sí misma es una coalgebra sobre laC
cual se especifican los métodos y propiedades de los objetos.Como se muestra en el ejemplo de álgebra, si tenemos un montón de funciones como
a → τ
yb → τ
para cualquieraa, b,…
, podemos combinarlas todas en una sola función usandoEither
un tipo de suma. La "noción" dual sería combinar un montón de funciones de tipoτ → a
,τ → b
y así sucesivamente. Podemos hacer esto usando el doble de un tipo de suma: un tipo de producto. Entonces, dadas las dos funciones anteriores (llamadasf
yg
), podemos crear una sola de esta manera:El tipo
(a, a)
es un functor de forma directa, por lo que sin duda encaja con nuestra noción de un F-coalgebra. Este truco en particular nos permite agrupar un montón de funciones diferentes, o, para OOP, métodos, en una sola función de tipoτ → f τ
.Los elementos de nuestro tipo
C
representan el estado interno del objeto. Si el objeto tiene algunas propiedades legibles, deben poder depender del estado. La forma más obvia de hacer esto es hacer que funcionenC
. Entonces, si queremos una propiedad de longitud (por ejemploobject.length
), tendríamos una funciónC → Int
.Queremos métodos que puedan tomar un argumento y modificar el estado. Para hacer esto, necesitamos tomar todos los argumentos y producir uno nuevo
C
. Imaginemos unsetPosition
método que toma unax
y unay
de coordenadas:object.setPosition(1, 2)
. Se vería así:C → ((Int, Int) → C)
.El patrón importante aquí es que los "métodos" y las "propiedades" del objeto toman el objeto mismo como su primer argumento. Esto es como el
self
parámetro en Python y como el implícitothis
de muchos otros lenguajes. Un coalgebra esencialmente sólo encapsula el comportamiento de tomar unself
parámetro: eso es lo que la primeraC
enC → F C
es.Así que vamos a poner todo junto. Imaginemos una clase con una
position
propiedad, unaname
propiedad y unasetPosition
función:Necesitamos dos partes para representar esta clase. Primero, necesitamos representar el estado interno del objeto; en este caso solo tiene dos
Int
sy aString
. (Este es nuestro tipoC
). Entonces tenemos que llegar a la coalgebra que represente a la clase.Tenemos dos propiedades para escribir. Son bastante triviales:
Ahora solo necesitamos poder actualizar la posición:
Esto es como una clase de Python con sus
self
variables explícitas . Ahora que tenemos un montón deself →
funciones, necesitamos combinarlas en una sola función para el coalgebra. Podemos hacer esto con una simple tupla:El tipo
((Int, Int), String, (Int, Int) → c)
-por cualquierc
-es un funtor, por lo quecoop
tiene la forma que queremos:Functor f ⇒ C → f C
.Dado esto,
C
junto concoop
formar un coalgebra que especifica la clase que di arriba. Puede ver cómo podemos usar esta misma técnica para especificar cualquier número de métodos y propiedades para que nuestros objetos tengan.Esto nos permite usar el razonamiento coalgebraico para tratar con las clases. Por ejemplo, podemos incorporar la noción de un "homomorfismo de F-coalgebra" para representar transformaciones entre clases. Este es un término que suena aterrador y solo significa una transformación entre coalgebras que preserva la estructura. Esto hace que sea mucho más fácil pensar en asignar clases a otras clases.
En resumen, un F-coalgebra representa una clase al tener un conjunto de propiedades y métodos que dependen de un
self
parámetro que contiene el estado interno de cada objeto.Otras categorias
Hasta ahora, hemos hablado de álgebras y coalgebras como los tipos de Haskell. Un álgebra es solo un tipo
τ
con una funciónf τ → τ
y un coalgebra es solo un tipoτ
con una funciónτ → f τ
.Sin embargo, nada vincula realmente estas ideas con Haskell per se . De hecho, generalmente se introducen en términos de conjuntos y funciones matemáticas en lugar de tipos y funciones de Haskell. De hecho, podemos generalizar estos conceptos a cualquier categoría.
Podemos definir un F-álgebra para alguna categoría
C
. Primero, necesitamos un functorF : C → C
, es decir, un endofunctor . (Todo HaskellFunctor
s son en realidad endofunctors deHask → Hask
.) Entonces, un álgebra es sólo un objetoA
a partirC
de un morfismoF A → A
. Un coalgebra es lo mismo excepto conA → F A
.¿Qué ganamos al considerar otras categorías? Bueno, podemos usar las mismas ideas en diferentes contextos. Como mónadas. En Haskell, una mónada es de algún tipo
M ∷ ★ → ★
con tres operaciones:La
map
función es solo una prueba del hecho de queM
es aFunctor
. Entonces, podemos decir que una mónada es solo un functor con dos operaciones:return
yjoin
.Los functores forman una categoría ellos mismos, con morfismos entre ellos llamados "transformaciones naturales". Una transformación natural es solo una forma de transformar un functor en otro mientras preserva su estructura. Aquí hay un buen artículo que ayuda a explicar la idea. Habla de eso
concat
, que es solojoin
para listas.Con los functores Haskell, la composición de dos functores es un functor en sí mismo. En pseudocódigo, podríamos escribir esto:
Esto nos ayuda a pensar
join
como un mapeo def ∘ f → f
. El tipo dejoin
es∀α. f (f α) → f α
. Intuitivamente, podemos ver cómo una función válida para todos los tiposα
puede considerarse como una transformación def
.return
Es una transformación similar. Su tipo es∀α. α → f α
. Esto se ve diferente: ¡el primeroα
no está "en" un functor! Afortunadamente, podemos solucionar este problema mediante la adición de un funtor identidad no:∀α. Identity α → f α
. Entoncesreturn
es una transformaciónIdentity → f
.Ahora podemos pensar en una mónada como un álgebra basada en algún functor
f
con operacionesf ∘ f → f
yIdentity → f
. ¿No te parece familiar? Es muy similar a un monoide, que era solo un tipoτ
de operacionesτ × τ → τ
y() → τ
.Entonces, una mónada es como un monoide, excepto que en lugar de tener un tipo, tenemos un functor. Es el mismo tipo de álgebra, solo que en una categoría diferente. (Aquí es donde la frase "Una mónada es solo un monoide en la categoría de endofunctores" proviene de lo que yo sé).
Ahora, tenemos estas dos operaciones:
f ∘ f → f
yIdentity → f
. Para obtener el coalgebra correspondiente, simplemente volteamos las flechas. Esto nos da dos nuevas operaciones:f → f ∘ f
yf → Identity
. Podemos convertirlos en tipos de Haskell agregando variables de tipo como arriba, dándonos∀α. f α → f (f α)
y∀α. f α → α
. Esto se parece a la definición de comonad:Entonces, una comonad es una coalgebra en una categoría de endofunctores.
fuente
(,)
y la identidad del functor()
. Un objeto monoide dentro de una categoría monoidal es un objeto con flechas correspondientes a su álgebra monoidal, que describe un objeto monoide en Hask con tipos de productos como la estructura monoidal. Un objeto monoide en la categoría de endofunctores en C es una mónada en C, así que sí, su comprensión es correcta. :]F-álgebras y F-coalgebras son estructuras matemáticas que son instrumentales en el razonamiento sobre los tipos inductivos (o tipos recursivos ).
Álgebras F
Comenzaremos primero con F-álgebras. Intentaré ser lo más simple posible.
Supongo que sabes lo que es un tipo recursivo. Por ejemplo, este es un tipo para una lista de enteros:
Es obvio que es recursivo; de hecho, su definición se refiere a sí misma. Su definición consta de dos constructores de datos, que tienen los siguientes tipos:
Tenga en cuenta que he escrito tipo de
Nil
como() -> IntList
, no simplementeIntList
. De hecho, estos son tipos equivalentes desde el punto de vista teórico, porque el()
tipo tiene solo un habitante.Si escribimos firmas de estas funciones de una manera más teórica, obtendremos
donde
1
es un conjunto de unidades (conjunto con un elemento) y laA × B
operación es un producto cruzado de dos conjuntosA
yB
(es decir, un conjunto de pares(a, b)
dondea
atraviesa todos los elementosA
yb
atraviesa todos los elementos deB
).Unión disjunta de dos conjuntos
A
yB
es un conjuntoA | B
que es una unión de conjuntos{(a, 1) : a in A}
y{(b, 2) : b in B}
. En esencia se trata de un conjunto de todos los elementos de ambosA
yB
, pero con cada uno de estos elementos 'marcado' como perteneciente a cualquiera de los dosA
oB
, por lo que cuando tomamos cualquier elemento deA | B
sabremos de inmediato si este elemento proviene deA
o desdeB
.Podemos 'unirnos'
Nil
yCons
funciones, por lo que formarán una sola función trabajando en un conjunto1 | (Int × IntList)
:De hecho, si la
Nil|Cons
función se aplica al()
valor (que, obviamente, pertenece al1 | (Int × IntList)
conjunto), entonces se comporta como si lo fueraNil
; siNil|Cons
se aplica a cualquier valor de tipo(Int, IntList)
(tales valores también están en el conjunto1 | (Int × IntList)
, se comporta comoCons
.Ahora considere otro tipo de datos:
Tiene los siguientes constructores:
que también se puede unir en una función:
Se puede ver que ambas
joined
funciones tienen un tipo similar: ambas parecendonde
F
es una especie de transformación que tiene nuestro tipo y da tipo más complejo, que consiste enx
y|
operaciones, usos deT
y posiblemente otros tipos. Por ejemplo, paraIntList
yIntTree
F
tiene el siguiente aspecto:Podemos notar de inmediato que cualquier tipo algebraico se puede escribir de esta manera. De hecho, es por eso que se les llama 'algebraicos': consisten en una cantidad de 'sumas' (uniones) y 'productos' (productos cruzados) de otros tipos.
Ahora podemos definir F-álgebra. F-álgebra es solo un par
(T, f)
, dondeT
hay algún tipo yf
es una función de tipof :: F T -> T
. En nuestros ejemplos, las álgebras F son(IntList, Nil|Cons)
y(IntTree, Leaf|Branch)
. Tenga en cuenta, sin embargo, que a pesar de ese tipo def
función es la misma para cada F,T
y enf
sí mismas pueden ser arbitrarias. Por ejemplo,(String, g :: 1 | (Int x String) -> String)
o(Double, h :: Int | (Double, Double) -> Double)
para algunosg
yh
también son F-álgebras para F. correspondienteLuego podemos introducir homomorfismos de álgebra F y luego álgebras F iniciales , que tienen propiedades muy útiles. De hecho,
(IntList, Nil|Cons)
es un álgebra F1 inicial, y(IntTree, Leaf|Branch)
es un álgebra F2 inicial. No presentaré definiciones exactas de estos términos y propiedades, ya que son más complejos y abstractos de lo necesario.No obstante, el hecho de que, digamos,
(IntList, Nil|Cons)
es F-álgebra nos permite definir unafold
función similar a este tipo. Como sabe, fold es un tipo de operación que transforma algunos tipos de datos recursivos en un valor finito. Por ejemplo, podemos plegar una lista de enteros en un solo valor, que es la suma de todos los elementos de la lista:Es posible generalizar dicha operación en cualquier tipo de datos recursivo.
La siguiente es una firma de
foldr
función:Tenga en cuenta que he usado llaves para separar los dos primeros argumentos del último. Esta no es una
foldr
función real , pero es isomórfica (es decir, puede obtener fácilmente una de la otra y viceversa). Aplicado parcialmentefoldr
tendrá la siguiente firma:Podemos ver que esta es una función que toma una lista de enteros y devuelve un solo entero. Definamos dicha función en términos de nuestro
IntList
tipo.Vemos que esta función consta de dos partes: la primera parte define el comportamiento de esta función por
Nil
parte deIntList
, y la segunda parte define el comportamiento de la función porCons
parte.Ahora suponga que no estamos programando en Haskell sino en algún lenguaje que permita el uso de tipos algebraicos directamente en firmas de tipo (bueno, técnicamente Haskell permite el uso de tipos algebraicos a través de tuplas y
Either a b
tipos de datos, pero esto conducirá a verbosidades innecesarias). Considere una función:Se puede ver que
reductor
es una función de tipoF1 Int -> Int
, ¡como en la definición de F-álgebra! De hecho, el par(Int, reductor)
es un álgebra de F1.Debido a que
IntList
es una F1-álgebra inicial, para cada tipoT
y para cada funciónr :: F1 T -> T
no existe una función, llamada catamorphism parar
, que convierteIntList
aT
, y tal función es única. De hecho, en nuestro ejemplo un catamorphism parareductor
essumFold
. Tenga en cuenta cómoreductor
ysumFold
son similares: ¡tienen casi la misma estructura! El uso del parámetro enreductor
definicións
(cuyo tipo corresponde aT
) corresponde al uso del resultado del cálculo desumFold xs
ensumFold
definición.Solo para hacerlo más claro y ayudarlo a ver el patrón, aquí hay otro ejemplo, y nuevamente comenzamos desde la función de plegado resultante. Considere la
append
función que agrega su primer argumento al segundo argumento:Así se ve en nuestro
IntList
:Nuevamente, intentemos escribir el reductor:
appendFold
Es un catamorfismo para elappendReductor
que se transformaIntList
enIntList
.Entonces, esencialmente, las álgebras F nos permiten definir 'pliegues' en estructuras de datos recursivas, es decir, operaciones que reducen nuestras estructuras a algún valor.
F-coalgebras
F-coalgebras se denominan término 'dual' para F-álgebras. Nos permiten definir
unfolds
tipos de datos recursivos, es decir, una forma de construir estructuras recursivas a partir de algún valor.Supongamos que tiene el siguiente tipo:
Este es un flujo infinito de enteros. Su único constructor tiene el siguiente tipo:
O, en términos de conjuntos
Haskell le permite emparejar patrones en constructores de datos, para que pueda definir las siguientes funciones trabajando en
IntStream
s:Naturalmente, puede 'unir' estas funciones en una sola función de tipo
IntStream -> Int × IntStream
:Observe cómo el resultado de la función coincide con la representación algebraica de nuestro
IntStream
tipo. Algo similar también se puede hacer para otros tipos de datos recursivos. Quizás ya hayas notado el patrón. Me refiero a una familia de funciones de tipodonde
T
hay algun tipo De ahora en adelante definiremosAhora, F-coalgebra es un par
(T, g)
, dondeT
es un tipo yg
es una función del tipog :: T -> F T
. Por ejemplo,(IntStream, head&tail)
es un F1-coalgebra. De nuevo, al igual que en F-álgebras,g
yT
puede ser arbitrario, por ejemplo,(String, h :: String -> Int x String)
también es un F1-coalgebra por alguna h.Entre todas las F-coalgebras hay las llamadas F-coalgebras terminales , que son duales a las F-álgebras iniciales. Por ejemplo,
IntStream
es un terminal F-coalgebra. Esto significa que para cada tipoT
y para cada funciónp :: T -> F1 T
existe una función, llamada anamorfosis , que convierteT
aIntStream
, y tal función es única.Considere la siguiente función, que genera un flujo de enteros sucesivos a partir del dado:
Ahora inspeccionemos una función
natsBuilder :: Int -> F1 Int
, es decirnatsBuilder :: Int -> Int × Int
:De nuevo, podemos ver cierta similitud entre
nats
ynatsBuilder
. Es muy similar a la conexión que hemos observado con reductores y pliegues anteriormente.nats
Es un anamorfismo paranatsBuilder
.Otro ejemplo, una función que toma un valor y una función y devuelve un flujo de aplicaciones sucesivas de la función al valor:
Su función constructora es la siguiente:
Entonces
iterate
es un anamorfismo paraiterateBuilder
.Conclusión
En resumen, las álgebras F permiten definir pliegues, es decir, operaciones que reducen la estructura recursiva a un valor único, y las álgebras F permiten hacer lo contrario: construir una estructura [potencialmente] infinita a partir de un valor único.
De hecho, en Haskell F-álgebras y F-coalgebras coinciden. Esta es una propiedad muy agradable que es consecuencia de la presencia del valor 'inferior' en cada tipo. Por lo tanto, en Haskell se pueden crear pliegues y despliegues para cada tipo recursivo. Sin embargo, el modelo teórico detrás de esto es más complejo que el que he presentado anteriormente, por lo que deliberadamente lo he evitado.
Espero que esto ayude.
fuente
appendReductor
ve un poco extraño y realmente no me ayudó a ver el patrón allí ... :) ¿Puede verificar que sea correcto? ... ¿Cómo deberían ser los tipos de reductor en general? En la definición der
allí, ¿estáF1
determinado por IntList o es una F arbitraria?Repaso del documento tutorial Un tutorial sobre (co) álgebras y (co) inducción debería brindarle una idea sobre el co-álgebra en informática.
A continuación hay una cita para convencerte,
Preludio, sobre la teoría de la categoría. La teoría de categorías debe ser renombrar la teoría de los functores. Como categorías son lo que uno debe definir para definir functors. (Además, los functores son lo que uno debe definir para definir las transformaciones naturales).
¿Qué es un functor? Es una transformación de un conjunto a otro que preserva su estructura. (Para más detalles hay mucha buena descripción en la red).
¿Qué es un álgebra F? Es el álgebra del functor. Es solo el estudio de la propiedad universal del functor.
¿Cómo se puede vincular a la informática? El programa se puede ver como un conjunto estructurado de información. La ejecución del programa corresponde a la modificación de este conjunto estructurado de información. Suena bien que la ejecución debe preservar la estructura del programa. Luego, la ejecución puede verse como la aplicación de un functor sobre este conjunto de información. (El que define el programa).
¿Por qué F-co-álgebra? Los programas son duales por esencia, ya que se describen por información y actúan en consecuencia. Entonces, principalmente, la información que compone el programa y los modifica puede verse de dos maneras.
Entonces, en esta etapa, me gustaría decir que,
Durante la vida de un programa, los datos y el estado coexisten, y se completan mutuamente. Son duales
fuente
Comenzaré con cosas que obviamente están relacionadas con la programación y luego agregaré algunas cosas de matemáticas, para mantenerlo lo más concreto y práctico posible.
Citemos a algunos informáticos sobre coinducción ...
http://www.cs.umd.edu/~micinski/posts/2012-09-04-on-understanding-coinduction.html
http://adam.chlipala.net/cpdt/html/Coinductive.html
http://www.alexandrasilva.org/#/talks.html
Relacionar el contexto matemático ambiental con las tareas de programación habituales.
¿Qué es "un álgebra"?
Las estructuras algebraicas generalmente se ven así:
Esto debería sonar como objetos con 1. propiedades y 2. métodos. O incluso mejor, debería sonar como firmas de tipo.
Los ejemplos matemáticos estándar incluyen monoide ⊃ grupo ⊃ vector-espacio ⊃ "un álgebra". Los monoides son como autómatas: secuencias de verbos (por ejemplo,
f.g.h.h.nothing.f.g.f
). Ungit
registro que siempre agrega el historial y nunca lo elimina sería un monoide pero no un grupo. Si agrega inversos (por ejemplo, números negativos, fracciones, raíces, eliminando el historial acumulado, deshaciendo un espejo roto), obtiene un grupo.Los grupos contienen cosas que se pueden sumar o restar juntas. Por ejemplo,
Duration
s se pueden agregar juntos. (PeroDate
s no puede). Las duraciones viven en un espacio vectorial (no solo un grupo) porque también pueden ser escaladas por números externos. (Una firma tipo descaling :: (Number,Duration) → Duration
.)Las álgebras ⊂ espacios vectoriales pueden hacer otra cosa: hay algunas
m :: (T,T) → T
. Llame a esto "multiplicación" o no, porque una vez que se vaIntegers
, es menos obvio qué debería ser la "multiplicación" (o "exponenciación" ).(Esta es la razón por la gente mira a () propiedades universales categoría-teórico: para decirles lo que la multiplicación debería hacer o ser como :
)
Álgebras → Coalgebras
La multiplicación es más fácil de definir de una manera que se siente no arbitraria, que la multiplicación, porque para continuar
T → (T,T)
, puede repetir el mismo elemento. ("mapa diagonal" - como matrices diagonales / operadores en teoría espectral)Counit es por lo general la traza (suma de elementos de la diagonal), aunque de nuevo lo que es importante es lo que su counit hace ;
trace
es solo una buena respuesta para matrices.La razón para mirar un espacio dual , en general, es porque es más fácil pensar en ese espacio. Por ejemplo, a veces es más fácil pensar en un vector normal que en el plano en el que es normal, pero puede controlar los planos (incluidos los hiperplanos) con vectores (y ahora estoy hablando del vector geométrico familiar, como en un trazador de rayos) .
Domar datos (no) estructurados
Los matemáticos podrían estar modelando algo divertido como TQFT , mientras que los programadores tienen que luchar con
+ :: (Date,Duration) → Date
),Paris
≠(+48.8567,+2.3508)
! Es una forma, no un punto),Los científicos de la computación, cuando hablan de carbongebras, generalmente tienen en mente operaciones fijas, como el producto cartesiano. Creo que esto es lo que la gente quiere decir cuando dice "Las álgebras son coalgebras en Haskell". Pero en la medida en que los programadores tienen que modelar tipos de datos complejos como
Place
,Date/Time
y, yCustomer
hacer que esos modelos se parezcan tanto al mundo real (o al menos a la visión del mundo real del usuario final) como sea posible, creo que los duales, podría ser útil más allá de solo set-world.fuente