haskell - que - ¿Cómo puedo unir el segundo argumento en una función pero no la primera(de una manera elegante)?
tipos de argumentacion (3)
Cómo enlazar el segundo argumento:
mapSub5 x = map (`sub` 5) x
En tu caso, puedes escribir
div2 = flip div 2
ghci> div2 10
5
Tenga en cuenta que en Haskell puede escribir operadores en forma de prefijo como (-)
. Es lo mismo que sub
en tu pregunta.
¿Hay alguna manera en Haskell de enlazar el segundo argumento pero no el primero de una función sin usar funciones lambda o definir otra función "local"?
Ejemplo. Tengo una función binaria como:
sub :: Int -> Int -> Int
sub x y = x - y
Ahora si quiero vincular el primer argumento, puedo hacerlo fácilmente usando (sub alguna expresión):
mapSubFrom5 x = map (sub 5) x
*Main> mapSubFrom5 [1,2,3,4,5]
[4,3,2,1,0]
Eso funciona bien si quiero unir los primeros n argumentos sin "brecha".
Si quiero vincular el segundo argumento pero no el primero, las dos opciones que conozco son más detalladas:
Ya sea a través de otra función local,
mapSub5 x = map sub5 x
where sub5 x = sub x 5
*Main> mapSub5 [1,2,3,4,5]
[-4,-3,-2,-1,0]
O usando lambda:
mapSub5 x = map (/x -> sub x 5) x
Si bien ambos funcionan bien, me gusta la elegancia de "sub 5" y me pregunto si existe una forma igualmente elegante de vincular el argumento n-th (n> 1) de una función.
Para n = 2 solo otra forma de vincular:
ghci> map (flip (-) 5) [1..5]
[-4,-3,-2,-1,0]
flip
, que produce una nueva función con los primeros dos argumentos invertidos, ya se ha mencionado como una solución directa.
Sin embargo, vale la pena señalar que Haskell define una buena sintaxis de infijo para operadores binarios.
Primero que nada, es simplemente
sub = (-)
Con paréntesis alrededor, todos los operadores son, sintácticamente también, funciones ordinarias. Ahora podemos curry operadores con alguna sintaxis especial. Encuadernación al primer operando:
addOne = (1 +)
... y al segundo
half = (/ 2)
Por lo tanto, su código se convierte
map (-5) [1..5]
Desafortunadamente, -5
es un número literal, pero entiendes el punto. :) Ahora ya que podemos convertir cualquier función en un operador binario colocando palos de respaldo a su alrededor como en
f x y == x `f` y
podemos usar esta sintaxis especial de operador para escribir
map (`sub` 5) [1..5]
Nota: currying el primer argumento es común, el segundo, como en su caso, es muy posible. Pero: no haría eso por otros argumentos. Las funciones de Haskell están escritas en un estilo que los comunes para curry están en el frente exactamente por esa razón.
Usar una sintaxis especial para argumentos adicionales parece demasiado implícito para mí. Simplemente use la lambda y déle a las variables nombres descriptivos.