在Haskell中调用函数 - 初学者问题

时间:2011-05-28 00:06:55

标签: haskell

刚开始学习Haskell。

我的内部有一个空的源文件:

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

现在,如果我这样做,我可以这样打电话给:

*Main> pe 1000
233168

如何从源文件中调用它?如果我有

pe 1000

它返回一个神秘的错误:

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

我需要在主要内容声明它吗?

2 个答案:

答案 0 :(得分:11)

是的,您需要将其连接到main功能。例如,

main = print (pe 1000)

如果您想要多次通话,可以将它们与do - 表示法合并:

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

答案 1 :(得分:10)

Haskell源文件包含一系列定义,而不是表达式。因此,您不能只将表达式放在文件的顶层,您必须将它放在定义的主体内。因为pe 1000不是定义,所以会出错。

但为什么这么神秘的错误信息呢? GHC有一个名为Template Haskell的扩展,它允许您在编译时以编程方式创建定义。为了实现这一点,它允许您将表达式放在通常只允许定义的位置并在编译时计算表达式并将表达式替换为其结果(必须是定义) - 这称为拼接,然后表达式称为拼接。这种拼接需要满足两个要求:

  1. 表达式中使用的任何标识符必须在不同的源文件中定义(这是必需的,以便在遇到表达式时已经编译了已使用的函数,因此可以在编译时调用)
  2. 表达式的类型必须是模板Haskell类型,它表示有效的定义。
  3. 因为你的表达式pe 1000出现在只允许定义的地方,GHC认为它是一个拼接。然而,由于它不符合上述标准中的第一个,即它在当前文件中定义而不是在不同文件中定义,GHC抱怨这一点。当然它也不符合第二个条件,但GHC在产生错误信息时还没有达到这个目的。如果在其他源文件中定义了pe,则会收到一条错误消息,抱怨pe类型错误。