2011-05-28 25 views
10

Acabo de empezar a aprender Haskell.Llamar a una función en Haskell - problema de principiante

que tienen un archivo fuente de vacío con esto dentro:

pe :: (Integral a) => a -> a 
pe y = sum [x | x <- [1..y-1], x `mod` 3 == 0 || x `mod` 5 == 0] 

Ahora si ghci esto, puedo llamar a PE de esta manera:

*Main> pe 1000 
233168 

Como llamar desde dentro de mi fuente ¿archivo? Si tengo

pe 1000 

devuelve un error críptico:

GHC stage restriction: `pe' 
    is used in a top-level splice or annotation, 
    and must be imported, not defined locally 
In the expression: pe 1000 

¿Es necesario declarar en el principal o algo?

Respuesta

11

Sí, necesita conectarlo a su función main. Por ejemplo,

main = print (pe 1000) 

Si usted quiere tener múltiples llamadas, puede combinarlos con do -notation:

main = do 
    print (pe 500) 
    print (pe 1000) 
+4

o 'main = mapM_ (print. Pe) [1..1000]' si necesita hacerlo para una gran cantidad de valores. – alternative

10

Un archivo de origen Haskell contiene una secuencia de definiciones, no expresiones. Entonces no puedes simplemente poner una expresión en el nivel superior del archivo, tienes que ponerlo dentro del cuerpo de una definición. Entonces, dado que pe 1000 no es una definición, se obtiene un error.

¿Pero por qué un mensaje de error tan críptico? GHC tiene una extensión llamada Template Haskell, que le permite crear definiciones de manera programática en tiempo de compilación. Para lograr esto, le permite poner una expresión en un lugar donde generalmente solo se permiten las definiciones y evalúa la expresión en tiempo de compilación y reemplazar la expresión con su resultado (que debe ser una definición); esto se conoce como empalme y la expresión es entonces llamado empalme. Tal empalme tiene que cumplir dos requisitos:

  1. cualesquiera identificadores usados ​​en la expresión se deben definir en un archivo de origen diferente (esto es necesario para que las funciones utilizadas ya se compilan cuando se encuentra la expresión y por lo tanto puede ser llamado durante el tiempo de compilación)
  2. El tipo de la expresión debe ser un tipo Plantilla Haskell que represente una definición válida.

Como su expresión pe 1000 aparece en algún lugar donde solo se permiten las definiciones, GHC supone que es un empalme. Sin embargo, dado que no cumple con el primero de los criterios anteriores, es decir, se define en el archivo actual en lugar de en un archivo diferente, GHC se queja de eso. Por supuesto, tampoco cumple la segunda condición, pero GHC aún no ha llegado a eso, cuando produce el mensaje de error. Si pe se definieron en un archivo de origen diferente, habría recibido un mensaje de error quejándose del hecho de que pe tiene el tipo incorrecto.

+0

Gracias; muy apreciado. –

Cuestiones relacionadas