Considere el operador de composición de funciones monádicas <=<
. Esto es análogo a .
, excepto que funciona en funciones monádicas. Se puede definir simplemente en términos de >>=
, por lo que aprender sobre uno nos educará sobre el otro.
(<=<) :: (a -> m b) -> (b -> m c) -> a -> m c
(f <=< g) x = g x >>= f
(.) :: (a -> b) -> (b -> c) -> a -> c
(f . g) x = g x |> f
where z |> h = h z
En el caso de .
, g
se "realizó" primero, y luego f
se lleva a cabo en la salida del g
. En el caso de <=<
, g
y sus efectos se "realizan" primero, y luego f
y se realizan sus efectos. Es un poco inapropiado decir que uno sucede "antes" que el otro, en realidad, ya que no todas las mónadas funcionan de esa manera.
Quizás es más exacto decir que f
puede aprovechar la información contextual adicional proporcionada por g
. Pero que es no del todo correcto, ya que g
podría potencialmente llevar información contextual. Si quieres describir las mónadas al 100%, realmente tienes que caminar sobre cáscaras de huevo.
Pero en casi todos los casos no triviales, f <=< g
significa que los efectos (así como el resultado ) de la función monádica g
influirán posteriormente el comportamiento de la función monádica f
.
Para hacer frente a preguntas sobre v >>= f = join (fmap f v)
Considere f :: a -> m b
y v :: m a
. ¿Qué significa fmap f v
? Bien fmap :: (c -> d) -> m c -> m d
, y en este caso c = a
y d = m b
, entonces fmap f :: m a -> m (m b)
. Ahora, por supuesto, podemos aplicar v :: m a
a esta función, lo que resulta en m (m b)
. pero ¿qué exactamente tiene ese tipo de resultado m (m b)
?
interiorm
representa el contexto de producido a partir de f
. El exteriorm
representa el contexto que se origina en v
(n.b. fmap
no debe alterar este contexto original).
Y luego usted join
que m (m b)
, rompiendo esos dos contextos juntos en m a
. Este es el corazón de la definición de Monad
: debe proporcionar una forma de destruir contextos. Puede inspeccionar los detalles de implementación de varias instancias Monad
para tratar de comprender cómo "destruyen" contextos juntos. Sin embargo, la conclusión aquí es que el "contexto interno" es inobservable hasta que se fusiona con el "contexto externo". Si usa v >>= f
, entonces no hay noción real de de la función f
que recibe un valor puro a
y produce un resultado monádico simple m b
. En su lugar, entendemos que f
actúa dentro del contexto original de v
.
Creo que '>> =' representa más el aspecto de "fontanería" de una mónada, que es prácticamente importante, pero teóricamente bastante poco interesante. Descubrí que a menudo es más fácil implementar 'join' que'> = 'para una mónada, y supongo que hubiera sido más inteligente usar' join' para definir una mónada. – Landei
Posiblemente relevante: http://stackoverflow.com/questions/8221395/what-is-a-monad-in-fp-in-categorical-terms –
@Landei siempre puede definirlo como 'a >> = f = join (fmap fa) donde join = ...; ', suponiendo una instancia' Functor' ya existente. –