Duplicar posible:
Why is such a function definition not allowed in haskell?Haskell "Aplicar"?
yo soy un recién llegado al mundo de Haskell, migrando el relevo de Lisp. Estoy tratando de adaptarme 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 de Lisp: apply
. Para aquellos que no saben, apply toma una función y una lista de argumentos, e invoca la función en esos argumentos. En el esquema, (apply + '(1 2 3))
es el mismo que invocar (+ 1 2 3)
, y devuelve 6.
Mi Haskell es como la siguiente:
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 yo entender porqué. El tipo de Apply debe ser diferente según la longitud de la lista que se le dé. Dada una lista de, digamos, 3 elementos, el tipo de solicitud debería ser: (a -> a -> a -> b) -> [a] -> b
, pero dada una lista de 6 elementos, el tipo de solicitud debería ser: (a -> a -> a -> a -> a -> a -> b) -> [a] -> b
.
yo probamos este trabajo en torno horrendo:
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 apenas cuenta como una función apply
, porque no puedo pasar apply
una función normal, tengo que usar uno que ha sido escrito específicamente para usar mi (incómoda) abstracción FnOrDat. Si quisiera escribir una función que agregara cuatro números, necesitaría escribir
add4 a = Fn (\b -> Fn (\c -> Fn (\d -> Dat (a + b + c + d))))
Ew.
Entonces, ¿me falta algo, o estoy pidiendo un apply
de propósito general básicamente como pedir una función que pueda manipular una tupla de longitud arbitraria? ¿Tiene sentido el apply
en la cosmovisión de tipo estático de Haskell?
Gracias! En realidad, uso GHC en mi computadora "principal". Estoy escribiendo esto en otro lugar, así que acabo de usar codepad.org para probar mis fragmentos de código. Supongo que usan abrazos? – Ord
@Ord usan abrazos, con el indicador '-98'. Ver http://codepad.org/about –