25 votos

¿Puede alguien explicarme por qué la función de la aplicación de la ArrowApply hace tan potente como mónadas?

Así que me voy a romper mi pregunta en 4 partes, pero primero algunos antecedentes:

Me siento bastante cómodo con las Mónadas, pero no muy cómodo con las Flechas. Supongo que el principal problema que tengo con ellos es, no veo lo que son útiles para. Ya sea formalmente correcta o no, entiendo Mónadas a ser una herramienta que nos permite introducir los efectos secundarios de la computación. Como generalizan fragmentos de programa desde el más puro de los valores valores en caja con otras acciones. Desde mi escopeta "leído todos los documentos" enfoque de aprendizaje acerca de flechas, he llegado a través de dos puntos de vista opuestos:

A. las Flechas son más poderosas que las Mónadas son generalizaciones de las Mónadas. La haskell wiki comienza con "todo Se puede mónadas puede hacer, y más. Ellos son más o menos comparables a las mónadas con un componente estático."

B. las Flechas son un subconjunto de las Mónadas Con ArrowApply podemos definir una monada

  1. ¿Hay alguna verdad a Un punto de vista?
  2. ¿Qué tipo de funcionalidad de hacer flechas no tienen, he leído que la diferencia tiene que ver con la composición, así que ¿qué hace el >>> operador nos permite hacer que >>= no?
  3. Lo que hace la aplicación es exactamente lo que? es el tipo ni siquiera tiene un (->)
  4. ¿Por qué queremos utilizar aplicativo flechas sobre las mónadas?

10voto

Tikhon Jelvis Puntos 30789

Punto de vista, es Un poco extraño, generalmente hablando, una abstracción que no va a ser tanto más poderoso y más general que el de algunos otros de la abstracción; los dos están en desacuerdo. Tener "más poder", significa saber más acerca de la estructura de lo que usted está trabajando, lo que significa más restricciones. En un extremo, de saber exactamente qué tipo usted está trabajando. Esto es extremadamente potente; se puede aplicar cualquier función válida. Por otro lado, tampoco es general en lo más mínimo: el código escrito con este supuesto sólo se aplica a ese tipo! En el otro extremo, se puede saber nada acerca de su tipo (por ejemplo, tener un tipo de variable a). Esto es muy general, se aplica a cada tipo, pero también no es poderoso, ya que usted no tiene la información suficiente para hacer nada en absoluto!

Un ejemplo más arraigada en el código real es la diferencia entre Functor y Applicative. Aquí, Functor es más general--estrictamente más tipos de Functors de Applicatives, ya que cada Applicative es también una Functor pero no viceversa. Sin embargo, desde Applicative lleva más de la estructura, es estrictamente más potente. Con Functor, sólo puedes mapa de un solo argumento de las funciones de su tipo; con Applicative, puede asignar funciones de cualquier número de argumentos. De nuevo: uno es más general, el otro más potente.

Así que es? Las flechas que se encuentran más potentes o más general que las mónadas? Esta es una pregunta más difícil de comparar functors, aplicativo functors y mónadas porque flechas son muy diferentes a las de la bestia. Incluso tienen un tipo diferente: las mónadas et al tener un tipo * -> * donde las flechas tienen tipo * -> * -> *. Felizmente, resulta que podemos identificar flechas con aplicativo functors/mónadas, por lo que podemos responder a esta pregunta de manera significativa: las flechas son más generales que las mónadas y, en consecuencia, menos potente. Dado cualquier mónada, podemos construir una flecha fuera de él, pero no podemos construir una monada para cada flecha.

La idea básica es la siguiente:

instance Monad m => Category (a -> m b) where
  id = return
  (f . g) x = g x >>= f

instance Monad m => Arrow (a -> m b) where
  arr f = return . f
  first f (x, y) = f x >>= \ x' -> return (x', y)

Sin embargo, ya que tienen una flecha instancia para a -> b, tenemos que rodear a -> m b a una newtype en el código real. Este newtype se llama Klesli (debido a Klesli categorías).

Sin embargo, no podemos ir a otro lado-no existe la construcción de obtener un Monad de cualquier Arrow. Esto sucede porque un Arrow cálculo no puede cambiar su estructura basada en los valores que fluye a través de él, mientras que las mónadas puede. La única forma de evitar esto es para añadir potencia a la flecha de su abstracción con más primitiva de la función; esto es exactamente lo ArrowApply .

El >>> operador de flechas es una generalización de . para las funciones, y por lo tanto tiene las mismas restricciones generales. >>=, por otro lado, es más como una generalización de la función de la aplicación. Nota los tipos: para >>>, ambos lados están flechas; >>=, el primer argumento es un valor (m a) y la segunda de una función. Por otra parte, el resultado de >>> es otra flecha donde el resultado de >>= es un valor. Desde flechas sólo tiene >>> pero hay noción equivalente a >>=, que no se puede "aplicar" a los argumentos en general, que sólo se puede construir flecha tuberías. El real aplicar/ejecutar la función tendría que ser específico para cualquier flecha. Las mónadas, por otro lado, se definen en términos de >>= , y así con una cierta noción de la aplicación por defecto.

ArrowApply sólo se extiende flechas app, que es una noción general de la aplicación. Imaginemos la función normal de la aplicación:

apply :: (b -> c) -> b -> c
apply f x = f x

podemos uncurry esto para obtener:

apply :: ((b -> c), b) -> c

El camino de las flechas de generalizar las funciones es, básicamente, mediante la sustitución de -> con una variable (a). Vamos a hacer esto para apply mediante la sustitución de los dos accesos de la -> con un infijo a:

apply :: (b `a` c, b) `a` c

Todavía podemos ver la misma estructura que la primera versión de apply, sólo uncurried y con `a` en lugar de ->. Ahora si que se acaba de deshacerse de las comillas simples inclinadas y hacer a prefijo, se obtiene la firma de app:

app :: a (a b c, b) c

Así vemos cómo ArrowApply sólo añade una cierta noción de la aplicación de las flechas. Este es un prallel a >>=, que es un concepto de aplicación de las mónadas (o, en particular, las funciones de la forma a -> m b). Esto es suficiente estructura adicional para construir una monada de una flecha, por lo ArrowApply es isomorfo a Monad.

¿Por qué queremos utilizar estas? Honestamente, no creo que lo haría. Las flechas son bastante sobrevalorado, por lo que se adhieren a las mónadas y aplicativo functors.

1voto

wit Puntos 1359

Mónada es un instrumento que nos permite escribir en el imperativo de estilo (paso por paso).

La flecha es un instrumento que nos permite escribir en el diagrama de bloques de estilo.

Así, la mónada para flechas parece lineal del diagrama de bloques.

http://www.soi.city.ac.uk/~ross/charlas/fop.pdf

http://www.haskell.org/arrows/syntax.html

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X