【问题标题】:Error specified for negative numbers displayed when function applied to a Fractional. Why?当函数应用于小数时,为负数指定的错误。为什么?
【发布时间】:2017-12-17 14:26:07
【问题描述】:

我正在尝试学习 Haskell,我定义了以下简单的递归函数来计算阶乘。

fact n | n < 0 = error "fact only valid for non-negative integers"
       | n == 0 = 1
       | n > 0 = n * fact(n-1)

它适用于正整数,并且正如预期的那样,当使用负整数调用时,它会抛出我指定的错误。

有什么问题?:当我尝试将它应用于分数时,它给了我同样的错误(“事实仅对非负整数有效”),例如fact 10.5。为什么它给我同样的错误,我已经明确指出应该只适用于 n

【问题讨论】:

    标签: haskell recursion


    【解决方案1】:

    如果你给它 10.5 作为参数,那么第三种情况是有效的,并且函数使用 n = 10.5 - 1 = 9.5 递归调用自身。

    该输入还会触发第三种情况,使用n = 8.5 进行递归调用。

    依此类推:7.5、6.5、5.5、4.5、3.5、2.5、1.5、0.5

    然后,在下一次迭代中,n = -0.5 会触发第一种情况并产生错误。一切都与编码完全相同。

    如果您希望您的函数适用于小数,您必须 (a) 为 0 &lt; n &lt; 1 定义 n 的阶乘,然后 (b) 对这种情况进行编码。

    例如,如果我要定义一个介于 0 和 1 之间的数字的阶乘等于 1,那么函数将如下所示:

    fact n | n < 0 = error "fact only valid for non-negative integers"
           | n >= 0 && n <= 1 = 1
           | n > 0 = n * fact(n-1)
    

    另外,附注:我认为上面的代码应该给你一个警告,这个函数是不完整的。这是因为编译器无法证明其中一种情况应该始终成立(并且公平地说,取决于参数类型和NumOrd 的定义,它可能不成立)。为避免这种情况,应使用otherwise 子句:

    fact n | n < 0 = error "fact only valid for non-negative integers"
           | n >= 0 && n <= 1 = 1
           | otherwise = n * fact(n-1)
    

    【讨论】:

    • 谢谢!当然,这是有道理的。我应该知道这一点的。当它允许我这样做时会接受答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    • 2010-11-22
    • 1970-01-01
    • 2021-10-04
    • 2011-01-17
    • 1970-01-01
    相关资源
    最近更新 更多