2017-10-17 160 views
1

我在编写Haskell中的简单函数时遇到了麻烦......它意在计算从1到n的数字之和。我不允许使用if语句,因为我的老师希望我们专注于函数式编程。任何帮助,将不胜感激。谢谢!Haskell中的求和 - 函数式编程

summation :: Integer -> Integer 
summation n 
    | n > 1 = n + summation(n-1) 
    | n == 1 = 1 

这是GHCI输出:

clase4.hs:13:28: error: 
    Variable not in scope: (?) :: Integer -> Integer -> Integer 
Failed, modules loaded: none. 

线13:

 | n > 1 = n + summation(n-1) 

我评论说一切在该文件中,我仍然得到这个错误。我看不见 '?'任何地方。这是屏幕截图:

File

GHCi output

+4

'?'是不是该代码。你可以创建一个[mcve]吗? – 4castle

+0

顺便说,有一个[对于更有效的算法(https://en.wikipedia.org/wiki/1_%2B_2_%2B_3_%2B_4_%2B_%E2%8B%AF#Partial_sums)。 – 4castle

+0

这就是我写的'?'没有出现在文件的任何地方 –

回答

10

在源文件中clase4.hs,你认为是在表达一个标准的ASCII字符的减号n-1不是字符。相反,你可能使用了一些其他的Unicode字符,像一个“破折号”或东西,只有看起来像一个减号(也许是因为你编辑的文件在Microsoft Word等奇怪的东西或复制和粘贴代码从一些与角色混淆的来源)。

Haskell是打印无效字符为“?”因为,就其可以说,您的输出终端不支持显示错误字符所需的编码。 (这是在Windows环境下运行Haskell时的一个常见问题,虽然它可能发生在其他平台上,如果事情设置很奇怪。)

用适当的文本编辑器打开源文件,突出显示“减号”,然后重新键入您的键盘。在西班牙语键盘上,这应该是右下角Shift键左侧的关键;在美式键盘上,它位于零键的右侧。

如果失败,尝试复制和从堆栈溢出上面粘贴自己的程序进入一个全新的文本文件,并编译 - 复制,并从你的问题粘贴为我们其余的正常工作。

+0

就是这样!改变角色的工作,我仍然不知道我是如何倾倒它,为什么当我粘贴代码在这里成为一个负号,但我不认为这是非常重要的。非常感谢!! –

1

在我看来,有两个问题在这里:

  1. 您的递归调用调用sumatoria而你的函数是summation;
  2. 你检查n > 1n == 1这是相当不安全的。

我们可以通过summation subsituting sumatoria解决的问题,使警卫更安全:

summation :: Integer -> Integer 
summation n 
    | n >= 1 = n + summation (n-1) 
    | otherwise = 0

现在,它应该工作。我们使用otherwise = 0,如果我们输入0或负数,我们获得0

尽管如此,我们仍然可以改进这个功能。首先,我们不应该只限于Integer s。我们可以使用任何种类的Num埃里克类型aOrd erable。通过使用

summation :: (Num a, Ord a) => a -> a 
summation n 
    | n > 1 = n + summation (n-1) 
    | otherwise = 0

,此外的1..n0..n可以计算的总和::所以我们可以把它改写为

n 
--- 
\   n * (n+1) 
/ i = --------- 
---   2 
i=1

所以我们可以把它写成:

summation :: Integral a => a -> a 
summation n = div (n * (n+1)) 2 

div :: Integral a => a -> a -> a要求aIntegral。如果乘法,增量和除法全部都是O(1)操作,则这是现在的函数。

最后要注意的是,除了使用递归之外,还可以使用像sum这样的函数。在这种情况下,你也可以使用:

summation :: (Enum a, Num a) => a -> a 
summation n = sum [1..n] 
+0

非常感谢!原始文件是西班牙文,所以它在任何地方都可以读到sumatoria,我已经把它翻译成总结在这里发布,并忘记改变它。我喜欢你的方法,但我仍然想明白为什么我没有工作。 –

+0

@SantiagoAguilar:您的源代码在两个变量之间包含问号“?”。但我们看不到。 –

+0

我看不到'?'任何地方。我已经上传了文件和输出的图片。谢谢!! –