我最近读了一篇论文,其中阶乘的定义如下:
fac 0 = 1
fac (n + 1) = (n + 1) ∗ fac n
我实现了论文中的程序如下:
factorial :: Integer -> Integer
fac 0 = 1
fac (n + 1) = (n + 1) ∗ fac n
然后我尝试使用
Num a
作为替代方案,认为类型签名可能是问题所在。
factorial :: Num a => a -> a
fac 0 = 1
fac (n + 1) = (n + 1) ∗ fac n
但是当我尝试使用 GHCi 编译此文件时,对于这两个问题我都会收到以下错误:
Factorial.hs:5:6: error: Parse error in pattern: n + 1
|
5 | fac (n + 1) = (n + 1) ∗ fac n
谁能解释一下为什么会出现这个错误?
谢谢
我已经尝试实现论文中的代码,如图所示。我还添加了论文中没有的类型签名。然后我在类型签名中尝试了一种限制较少的类型。都有同样的错误。
默认情况下,
n+1
目前不是正确的 Haskell 模式。过去,Haskell 确实有这样的“n+k”模式,你的文档很可能是在支持 n+k 模式时编写的。
该功能仍然可以与最新的编译器一起使用,前提是显式打开 NPlusKPatterns
语言扩展。例如,以下代码按预期工作:
{-# LANGUAGE NPlusKPatterns #-}
fac :: Integral a => a -> a
fac 0 = 1
fac (n + 1) = (n + 1) * (fac n)
main :: IO()
main = do
putStrLn $ "Factorial of 7 is: " ++ (show $ fac 7)
Haskell 社区的很大一部分人开始将 n+k 模式视为错误特征,因此当 Haskell 2010 标准发布时,它们从语言中删除。所以正确的现代语法就是:
fac :: Integral a => a -> a
fac 0 = 1
fac n = n * (fac (n-1))
相关SO问题:请参阅what-are-nk-patterns-and-why-are-are-banned-from-haskell-2010