superior suma orden imprimir importar funciones funcion contador como comandos arreglos haskell types lisp polyvariadic

suma - Haskell "Aplicar"?



imprimir en haskell (3)

... una función que es muy importante en el mundo Lisp: aplicar . Para aquellos que no saben, aplicar toma una función y una lista de argumentos , e invoca la función en esos argumentos. En Esquema, (apply + ''(1 2 3)) es lo mismo que invocar (+ 1 2 3) , y devuelve 6 . ...

Esto es bastante simple:

foldr (+) 0 [1,2,3] foldr1 (+) [1,2,3]

resultados en 6.

Para aplicar una función a cada elemento de una lista:

map f list

p.ej

map (2*) [1,2,3]

resultados en [2,4,6]

¿Es esto lo que estás buscando?

Posible duplicado:
¿Por qué no se permite esta definición de función en haskell?

Soy un recién llegado al mundo de Haskell, migrando desde Lisp. Estoy tratando de ajustarme a la cosmovisión fundamentalmente diferente de Haskell, y una de las muchas cosas que encuentro nuevas y emocionantes es el sistema de tipos. Siendo un Lisper, pensé que intentaría implementar en Haskell una función que es muy importante en el mundo Lisp: apply . Para aquellos que no saben, aplicar toma una función y una lista de argumentos, e invoca la función en esos argumentos. En Esquema, (apply + ''(1 2 3)) es lo mismo que invocar (+ 1 2 3) , y devuelve 6.

Mi código de Haskell se parece a esto:

apply x [] = x apply f (x:xs) = apply (f x) xs

Pero Haskell se queja:

ERROR line 2 - Type error in function binding *** Term : apply *** Type : (b -> a) -> [b] -> a *** Does not match : a -> [b] -> a *** Because : unification would give infinite type

Y creo que entiendo por qué. El tipo de aplicación debe ser diferente dependiendo de la longitud de la lista que se proporciona. Dada una lista de, digamos, 3 artículos, el tipo de aplicación debería ser: (a -> a -> a -> b) -> [a] -> b , pero dada una lista de 6 artículos, el tipo de aplicación debería ser para ser: (a -> a -> a -> a -> a -> a -> b) -> [a] -> b .

Intenté este trabajo horrible:

data FnOrDat a b = Dat b | Fn (a -> FnOrDat a b) apply :: (FnOrDat a b) -> [a] -> (FnOrDat a b) apply x [] = x apply (Fn f) (x:xs) = apply (f x) xs apply (Dat _) _ = error "Cannot apply something which is not a function!" add a = Fn (/b -> Dat (a + b)) main = putStrLn $ show $ x where Dat x = apply (Fn add) [5,1]

Esto funciona, pero casi no cuenta como una función de apply , ya que no puedo aprobar una función normal, tengo que usar una que se ha escrito específicamente para usar mi (incómoda) abstracción FnOrDat. Si quisiera escribir una función que sumara cuatro números, necesitaría escribir

add4 a = Fn (/b -> Fn (/c -> Fn (/d -> Dat (a + b + c + d))))

Ew

Entonces, ¿me estoy perdiendo algo o estoy pidiendo una apply propósito general básicamente como pedir una función que pueda manipular una tupla de longitud arbitraria? ¿La apply tiene sentido incluso en la cosmovisión estática de Haskell?


A pesar de la explicación de Don, foldl1 (+) realidad agregaría todos los elementos de una lista. Por lo tanto, se podría decir que la familia de funciones de fold acerca bastante a la apply tal como lo describe el OP.


apply no es muy útil en Haskell, ya que no se puede asignar un tipo a la función. Como puedes ver en tu FnOrDat, básicamente estás incrustando un lenguaje Lisp en Haskell como un EDSL para forzar la entrada de algo.

¿Solicitar una aplicación de propósito general básicamente como pedir una función que pueda manipular una tupla de longitud arbitraria?

Exactamente. Puede crear instancias de clase de tipo para ciertas combinaciones útiles de tipos, pero simplemente no existe la necesidad o el uso de una aplicación general variada.

Como nota al margen, debe considerar la actualización a GHC y la plataforma Haskell , en lugar del obsoleto sistema Hugs, ya que se está perdiendo la mayoría de las bibliotecas, herramientas y funciones de lenguaje desarrolladas en los últimos 10 años.