No entiendo qué es "levantar". ¿Debería entender primero las mónadas antes de entender qué es un "ascensor"? (También soy completamente ignorante acerca de las mónadas :) ¿O alguien puede explicármelo con palabras simples?
haskell
functional-programming
GabiMe
fuente
fuente
Respuestas:
Levantar es más un patrón de diseño que un concepto matemático (aunque espero que alguien por aquí ahora me refute al mostrarme cómo los elevadores son una categoría o algo así).
Por lo general, tiene algún tipo de datos con un parámetro. Algo como
Suponga que encuentra muchos usos de
Foo
los tipos numéricos de toma (Int
,Double
etc.) y sigue teniendo que escribir código que desenvuelva estos números, los sume o los multiplique y luego los envuelva de nuevo. Puede cortocircuitar esto escribiendo el código de desenvolver y envolver una vez. Esta función se llama tradicionalmente "elevación" porque se ve así:En otras palabras, tiene una función que toma una función de dos argumentos (como el
(+)
operador) y la convierte en la función equivalente para Foos.Entonces ahora puedes escribir
Editar: más información
Por supuesto que puede
liftFoo3
,liftFoo4
y así sucesivamente. Sin embargo, esto a menudo no es necesario.Comienza con la observación
Pero eso es exactamente lo mismo que
fmap
. Entonces, en lugar deliftFoo1
escribirSi realmente quieres una regularidad completa, puedes decir
Si puedes convertirte
Foo
en un functor, quizás puedas convertirlo en un functor aplicativo. De hecho, si puede escribirliftFoo2
, la instancia aplicativa se ve así:El
(<*>)
operador de Foo tiene el tipoAplica la función envuelta al valor envuelto. Entonces, si puede implementar
liftFoo2
, puede escribir esto en términos de ello. O puede implementarlo directamente y no molestarseliftFoo2
, porque elControl.Applicative
módulo incluyee igualmente hay
liftA
yliftA3
. Pero en realidad no los usa muy a menudo porque hay otro operadorEsto te permite escribir:
El término
myFunction <$> arg1
devuelve una nueva función envuelta en Foo. Esto a su vez se puede aplicar al siguiente argumento usando(<*>)
, y así sucesivamente. Entonces, en lugar de tener una función de elevación para cada arity, solo tiene una cadena de candidatos.fuente
lift id == id
ylift (f . g) == (lift f) . (lift g)
.id
y.
son la identidad de la flecha y la composición de la flecha de alguna categoría, respectivamente. Por lo general, cuando se habla de Haskell, la categoría en cuestión es "Hask", cuyas flechas son funciones de Haskell (en otras palabras,id
y se.
refieren a las funciones de Haskell que conoce y ama).instance Functor Foo
, noinstance Foo Functor
, ¿verdad? Me editaría a mí mismo pero no estoy 100% seguro.Paul's y yairchu's son buenas explicaciones.
Me gustaría agregar que la función que se levanta puede tener un número arbitrario de argumentos y que no tienen que ser del mismo tipo. Por ejemplo, también podría definir un liftFoo1:
En general, el levantamiento de funciones que toman 1 argumento se captura en la clase de tipo
Functor
, y la operación de levantamiento se llamafmap
:Tenga en cuenta la similitud con
liftFoo1
el tipo de. De hecho, si tieneliftFoo1
, puede hacerFoo
una instancia deFunctor
:Además, la generalización de levantar a un número arbitrario de argumentos se llama estilo aplicativo . No se moleste en sumergirse en esto hasta que comprenda el levantamiento de funciones con un número fijo de argumentos. Pero cuando lo haces, Learn you a Haskell tiene un buen capítulo sobre esto. El Typeclassopedia es otro buen documento que describe Functor y Aplicativo (así como otras clases de tipos; de desplazamiento hacia abajo a la derecha capítulo en ese documento).
¡Espero que esto ayude!
fuente
Comencemos con un ejemplo (se agrega algo de espacio en blanco para una presentación más clara):
liftA2
transforma una función de tipos simples en una función de los mismos tipos envueltos en unApplicative
, como listasIO
, etc.Otro ascensor común es
lift
deControl.Monad.Trans
. Transforma una acción monádica de una mónada en una acción de una mónada transformada.En general, "levantar" eleva una función / acción a un tipo "envuelto" (por lo que la función original funciona "en secreto").
La mejor manera de entender esto, y mónadas, etc., y comprender por qué son útiles, es probablemente codificarlo y usarlo. Si hay algo que codificó anteriormente que sospecha que puede beneficiarse de esto (es decir, esto hará que ese código sea más corto, etc.), simplemente pruébelo y comprenderá fácilmente el concepto.
fuente
Lifting es un concepto que le permite transformar una función en una función correspondiente dentro de otra configuración (generalmente más general)
Echa un vistazo a http://haskell.org/haskellwiki/Lifting
fuente
De acuerdo con este tutorial brillante , un functor es un contenedor (como
Maybe<a>
,List<a>
oTree<a>
que puede almacenar elementos de algún otro tipoa
). He usado la notación genérica de Java<a>
para el tipo de elementoa
y pienso en los elementos como bayas en el árbolTree<a>
. Hay una funciónfmap
, que toma una función de conversión de elementosa->b
y un contenedorfunctor<a>
. Se aplicaa->b
a cada elemento del contenedor convirtiéndolo efectivamente enfunctor<b>
. Cuando solo se proporciona el primer argumentoa->b
,fmap
espera elfunctor<a>
. Es decir, el suministroa->b
solo convierte esta función de nivel de elemento en la funciónfunctor<a> -> functor<b>
que opera sobre contenedores. Esto se llama levantarde la función. Debido a que el contenedor también se llama functor , los Functors en lugar de las Mónadas son un requisito previo para el levantamiento. Las mónadas son algo "paralelas" a la elevación. Ambos confían en la noción de Functor y lo hacenf<a> -> f<b>
. La diferencia es que el levantamiento utilizaa->b
para la conversión, mientras que Monad requiere que el usuario lo definaa -> f<b>
.fuente
r
a un tipo (usemosc
para variedad), son Functores. No "contienen" ningunoc
. En este caso, fmap es la composición de funciones, tomando unaa -> b
función y unar -> a
, para darle una nuevar -> b
función. Todavía no hay contenedores. Además, si pudiera, lo marcaría nuevamente para la oración final.fmap
es una función y no "espera" nada; El "contenedor" siendo un Functor es el punto principal de elevación. Además, las mónadas son, en todo caso, una doble idea para levantar: una mónada le permite usar algo que se ha levantado un número positivo de veces, como si solo se hubiera levantado una vez; esto se conoce mejor como aplanamiento .To wait
,to expect
,to anticipate
son los sinónimos. Al decir "la función espera" quise decir "la función anticipa".b = 5 : a
yf 0 = 55
f n = g n
, ambos implican seudo mutar el "contenedor". También el hecho de que las listas generalmente se almacenan completamente en la memoria, mientras que las funciones se almacenan típicamente como un cálculo. Pero las listas memorables / monorfas que no se almacenan entre llamadas rompen esa idea.