【问题标题】:Haskell basic factorial not exiting? [duplicate]Haskell基本阶乘不退出? [复制]
【发布时间】:2013-04-12 18:11:35
【问题描述】:

我正在学习 Haskell,但在使用 this tutorial 的基本阶乘函数时遇到问题。

基本上,我已经定义了一个阶乘:

Prelude> let factorial 0 = 1
Prelude> let factorial n = n * factorial (n - 1)

类型检出:

Prelude> :t factorial
factorial :: Num a => a -> a

这是有道理的。但是,此函数的行为不会。无论输入是什么,它都会产生(interactive): out of memory

Prelude> factorial 5
(interactive): out of memory

我不得不假设这是一个导致内存不足错误的无限递归调用,但我不确定是什么可能导致它。 factorial 0 也会发生同样的事情,尽管我已明确声明它为 1:

Prelude> factorial 0
(interactive): out of memory

现在,奇怪的部分是:如果我在文件中定义阶乘函数,它就可以正常工作。我创建了一个文件tesths.hs s.t.:

factorial 0 = 1
factorial n = n * factorial (n - 1)

然后,如果我回到 GHCI 并运行 :l tesths.hs,我可以毫无错误地执行 factorial 5

这里发生了什么?

【问题讨论】:

    标签: haskell factorial


    【解决方案1】:

    定义了两个函数,而不是一个函数有两种情况。尝试首次运行 :set -Wall 的相同命令,您应该会收到名称阴影警告。要解决问题,请尝试

    let factorial 0 = 1; factorial n = n * factorial (n - 1)
    

    改为。

    【讨论】:

    • 嗯。有道理,我想。不过,这是一种奇怪的行为。
    • 是的。 ghci 中的let ... 真的是let ... in。这绝对不是 ghci 唯一有点奇怪的地方 - 结果显示不同,具体取决于其类型是 Show a => aShow a => IO a 还是 IO ()
    • 这有点道理。它取决于输入的类型,几乎任何语言都需要这种类型
    【解决方案2】:

    您也可以使用:{ ... :} 语法来提供多行输入:

    Prelude> :{
    Prelude| let factorial 0 = 1
    Prelude|     factorial n = n * factorial (n - 1)
    Prelude| :}
    Prelude> factorial 10
    3628800
    Prelude> 
    

    同样,您可以使用多行模式和缩进 :set +m:

    Prelude> :set +m
    Prelude> let factorial 0 = 1
    Prelude|     factorial n = n * factorial (n - 1)
    Prelude| 
    Prelude> factorial 10
    3628800
    Prelude> 
    

    注意空行。您可以使用:unset +m 关闭多行模式。

    请参阅 Section 2.4.3 of the GHC User's Guide, "[Using GHCi with] Multiline input" 了解有关这些内容的文档。

    【讨论】:

      【解决方案3】:

      请注意,也有这样漂亮的单行:

      let factorial n = product [1..n]
      
      猜你喜欢
      • 1970-01-01
      • 2016-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 2015-12-21
      • 1970-01-01
      相关资源
      最近更新 更多