Al mirar a través del Preludio de Haskell, veo una función const
:
const x _ = x
Parece que no puedo encontrar nada relevante con respecto a esta función.
¿Cuál es el punto de? ¿Alguien puede dar un ejemplo de dónde podría usarse esta función?
Al mirar a través del Preludio de Haskell, veo una función const
:
const x _ = x
Parece que no puedo encontrar nada relevante con respecto a esta función.
¿Cuál es el punto de? ¿Alguien puede dar un ejemplo de dónde podría usarse esta función?
backgroundColor :: Text -> Color
es para míbackgroundColor = const White
Respuestas:
Es útil para pasar a funciones de orden superior cuando no necesita toda su flexibilidad. Por ejemplo, el operador de secuencia monádica
>>
se puede definir en términos del operador de unión monádica comoEs algo más ordenado que usar una lambda.
e incluso puedes usarlo sin puntos
aunque no lo recomiendo particularmente en este caso.
fuente
map (const 42) [1..5]
resulta en[42, 42, 42, 42, 42]
.const
es útil para aplicar a un solo argumento para producir una función donde se necesita una (como pasar amap
).head = foldr const (error "Prelude.head: empty list")
Para agregar a la excelente respuesta directa de Hammar: las funciones humildes como
const
yid
son realmente útiles como una función de orden superior por la misma razón que son fundamentales en el cálculo del combinador de SKI .No es que crea que las funciones de preludio de Haskell fueron modeladas conscientemente a partir de ese sistema formal o algo así. Es solo que crear abstracciones ricas en Haskell es muy fácil, por lo que a menudo ves que este tipo de cosas teóricas surgen como prácticamente útiles.
Enchufe descarado, pero escribí en un blog sobre cómo la instancia de Applicative para
(->)
son en realidad los combinadoresS
y aquí , si ese es el tipo de cosas que te gustan.K
fuente
((->) e)
también es la mónada del lector, conReader
y similares simplementenewtype
envoltorios, y laask
función es entoncesid
, por lo que también es elI
combinador. Si nos fijamos en su lugar en base BCKW original del Haskell Curry,B
,K
, yW
sonfmap
,return
yjoin
respectivamente.Un ejemplo sencillo de uso
const
esData.Functor.(<$)
. Con esta función puedes decir: Tengo aquí un funtor con algo aburrido, pero en cambio quiero tener esa otra cosa interesante, sin cambiar la forma del funtor. P.ejLa definición es:
o escrito no como inútil:
Verá cómo
const
se usa aquí para "olvidarse" de la entrada.fuente
Muchas de las otras respuestas discuten aplicaciones relativamente esotéricas (al menos para los recién llegados) de
const
. Aquí hay uno simple: puede usarconst
para deshacerse de un lambda que toma dos argumentos, desecha el primero pero hace algo interesante con el segundo.Por ejemplo, la siguiente implementación (ineficiente pero instructiva) de
length
,se puede reescribir como
que es quizás más elegante.
De
const (1+)
hecho, la expresión es semánticamente equivalente a\_ acc -> 1 + acc
, porque toma un argumento, lo descarta y devuelve la sección(1+)
.fuente
Otro uso es implementar funciones miembro de clase que tienen un argumento ficticio que no debe evaluarse (utilizado para resolver tipos ambiguos). Ejemplo que podría estar en Data.bits:
Al usar const, decimos explícitamente que estamos definiendo valores constantes.
Personalmente, no me gusta el uso de parámetros ficticios, pero si se usan en una clase, esta es una forma bastante agradable de escribir instancias.
fuente
const
puede ser solo la implementación que busca junto con otras funciones. Aquí hay un ejemplo que descubrí.Digamos que queremos reescribir una estructura de 2 tuplas en otra estructura de 2 tuplas. Podría expresar esto así:
Puedo dar una definición sencilla con la coincidencia de patrones:
¿Qué pasa si quiero una solución inútil (tácita) para este tipo de reescrituras? Un poco de pensamiento y jugueteo más tarde, la respuesta es que podemos expresar cualquier reescritura con
(&&&), const, (.), fst, snd
. Tenga en cuenta que(&&&)
es deControl.Arrow
.La solución del ejemplo usando estas funciones es:
Tenga en cuenta la similitud con
(a,(c,(5,a)))
. ¿Y si reemplazamos&&&
con,
? Luego dice:Observa cómo
a
es el primer elemento del primer elemento, y eso es lo quefst.fst
proyecta. Observe cómoc
es el primer elemento del segundo elemento, y eso es lo quefst.snd
proyecta. Es decir, las variables se convierten en el camino hacia su fuente.const
nos permite introducir constantes. ¡Es interesante cómo el nombre se alinea con el significado!Entonces generalizó esta idea con Aplicativo para que pueda escribir cualquier función en un estilo sin sentido (siempre y cuando tenga el análisis de casos disponibles como funciones, como por ejemplo
maybe
,either
,bool
). Nuevamente,const
juega el papel de introducir constantes. Puede ver este trabajo en el paquete Data.Function.Tacit .Cuando comienzas de manera abstracta, en la meta, y luego trabajas hacia una implementación, puedes sorprenderte con las respuestas. Es decir, cualquier función puede ser tan misteriosa como cualquier engranaje de una máquina. Sin embargo, si retrocede para ver toda la máquina, puede comprender el contexto en el que ese engranaje es necesario.
fuente
Supongamos que desea crear una lista de
Nothings
igual a la longitud de una cadena. Comoconst
devuelve su primer argumento, no importa el segundo, puede hacer:o, más explícitamente:
fuente
Digamos que desea rotar una lista. Esta es una forma idiomática de hacerlo en Haskell:
rotate :: Int -> [a] -> [a] rotate _ [] = [] rotate n xs = zipWith const (drop n (cycle xs)) xs
Esta función comprime dos matrices con la función
const
, la primera es una matriz cíclica infinita, la segunda es la matriz con la que comenzó.const
actúa como verificación de límites y utiliza la matriz original para terminar la matriz cíclica.Ver: Rotar una lista en Haskell
fuente
Suponga que le gustaría generar todas las subsecuencias de una lista dada.
Para cada elemento de la lista, en un punto dado, puede elegir entre Verdadero (incluirlo en la subsecuencia actual) o Falso (no incluirlo). Esto se puede hacer usando la función filterM .
Me gusta esto:
Por ejemplo, queremos todas las subsecuencias de
[1..4]
.fuente