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 deEithers 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
Cque contiene todos los posibles estados internos de los objetos en la clase; la clase en sí misma es una coalgebra sobre laCcual 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 usandoEitherun tipo de suma. La "noción" dual sería combinar un montón de funciones de tipoτ → a,τ → by así sucesivamente. Podemos hacer esto usando el doble de un tipo de suma: un tipo de producto. Entonces, dadas las dos funciones anteriores (llamadasfyg), 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
Crepresentan 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 unsetPositionmétodo que toma unaxy unayde 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
selfparámetro en Python y como el implícitothisde muchos otros lenguajes. Un coalgebra esencialmente sólo encapsula el comportamiento de tomar unselfparámetro: eso es lo que la primeraCenC → F Ces.Así que vamos a poner todo junto. Imaginemos una clase con una
positionpropiedad, unanamepropiedad y unasetPositionfunción:Necesitamos dos partes para representar esta clase. Primero, necesitamos representar el estado interno del objeto; en este caso solo tiene dos
Intsy 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
selfvariables 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 quecooptiene la forma que queremos:Functor f ⇒ C → f C.Dado esto,
Cjunto concoopformar 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
selfpará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 HaskellFunctors son en realidad endofunctors deHask → Hask.) Entonces, un álgebra es sólo un objetoAa partirCde 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
mapfunción es solo una prueba del hecho de queMes aFunctor. Entonces, podemos decir que una mónada es solo un functor con dos operaciones:returnyjoin.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 solojoinpara 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
joincomo un mapeo def ∘ f → f. El tipo dejoines∀α. f (f α) → f α. Intuitivamente, podemos ver cómo una función válida para todos los tiposαpuede considerarse como una transformación def.returnEs 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 α. Entoncesreturnes una transformaciónIdentity → f.Ahora podemos pensar en una mónada como un álgebra basada en algún functor
fcon operacionesf ∘ f → fyIdentity → 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 → fyIdentity → f. Para obtener el coalgebra correspondiente, simplemente volteamos las flechas. Esto nos da dos nuevas operaciones:f → f ∘ fyf → 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
Nilcomo() -> 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
1es un conjunto de unidades (conjunto con un elemento) y laA × Boperación es un producto cruzado de dos conjuntosAyB(es decir, un conjunto de pares(a, b)dondeaatraviesa todos los elementosAybatraviesa todos los elementos deB).Unión disjunta de dos conjuntos
AyBes un conjuntoA | Bque 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 ambosAyB, pero con cada uno de estos elementos 'marcado' como perteneciente a cualquiera de los dosAoB, por lo que cuando tomamos cualquier elemento deA | Bsabremos de inmediato si este elemento proviene deAo desdeB.Podemos 'unirnos'
NilyConsfunciones, por lo que formarán una sola función trabajando en un conjunto1 | (Int × IntList):De hecho, si la
Nil|Consfunción se aplica al()valor (que, obviamente, pertenece al1 | (Int × IntList)conjunto), entonces se comporta como si lo fueraNil; siNil|Consse 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
joinedfunciones tienen un tipo similar: ambas parecendonde
Fes una especie de transformación que tiene nuestro tipo y da tipo más complejo, que consiste enxy|operaciones, usos deTy posiblemente otros tipos. Por ejemplo, paraIntListyIntTreeFtiene 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), dondeThay algún tipo yfes 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 deffunción es la misma para cada F,Ty enfsí mismas pueden ser arbitrarias. Por ejemplo,(String, g :: 1 | (Int x String) -> String)o(Double, h :: Int | (Double, Double) -> Double)para algunosgyhtambié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 unafoldfunció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
foldrfunción:Tenga en cuenta que he usado llaves para separar los dos primeros argumentos del último. Esta no es una
foldrfunción real , pero es isomórfica (es decir, puede obtener fácilmente una de la otra y viceversa). Aplicado parcialmentefoldrtendrá 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
IntListtipo.Vemos que esta función consta de dos partes: la primera parte define el comportamiento de esta función por
Nilparte deIntList, y la segunda parte define el comportamiento de la función porConsparte.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 btipos de datos, pero esto conducirá a verbosidades innecesarias). Considere una función:Se puede ver que
reductores 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
IntListes una F1-álgebra inicial, para cada tipoTy para cada funciónr :: F1 T -> Tno existe una función, llamada catamorphism parar, que convierteIntListaT, y tal función es única. De hecho, en nuestro ejemplo un catamorphism parareductoressumFold. Tenga en cuenta cómoreductorysumFoldson similares: ¡tienen casi la misma estructura! El uso del parámetro enreductordefinicións(cuyo tipo corresponde aT) corresponde al uso del resultado del cálculo desumFold xsensumFolddefinició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
appendfunción que agrega su primer argumento al segundo argumento:Así se ve en nuestro
IntList:Nuevamente, intentemos escribir el reductor:
appendFoldEs un catamorfismo para elappendReductorque se transformaIntListenIntList.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
unfoldstipos 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
IntStreams: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
IntStreamtipo. 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
Thay algun tipo De ahora en adelante definiremosAhora, F-coalgebra es un par
(T, g), dondeTes un tipo yges 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,gyTpuede 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,
IntStreames un terminal F-coalgebra. Esto significa que para cada tipoTy para cada funciónp :: T -> F1 Texiste una función, llamada anamorfosis , que convierteTaIntStream, 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
natsynatsBuilder. Es muy similar a la conexión que hemos observado con reductores y pliegues anteriormente.natsEs 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
iteratees 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
appendReductorve 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 derallí, ¿estáF1determinado 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). Ungitregistro 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,
Durations se pueden agregar juntos. (PeroDates 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 ;
tracees 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/Timey, yCustomerhacer 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