【问题标题】:Function type mismatch函数类型不匹配
【发布时间】:2018-04-27 16:51:56
【问题描述】:

我有一个函数类型的函数:

newtonRootSequence' :: Double -> Double -> [Double]     

及函数定义:

newtonRootSequence' xn d = [(xn + (d * (1/xn))) div 2] ++ newtonRootSequence' ((xn + (d * (1/xn))) div 2) d

在接收到两个值 xn 和 d 后,它应该计算给定函数的结果

[(xn + (d * (1/xn))) div 2]

但由于某种原因,编译器在启动时不接受该函数并出现错误:

无法匹配预期类型 '(Integer->Integer->Integer->) ->Integer -> Double 与实际类型 double 函数 (xn + (d * (1/xn))) div 2) 应用于两个参数

此错误发生在我尝试将方程的结果发送到递归步骤的部分

++ newtonRootSequence' ((xn + (d * (1/xn))) div 2) d

【问题讨论】:

  • 如果要将div用作中缀函数,则需要使用反引号,即`div`
  • 此外 div 只接受积分。

标签: haskell recursion type-mismatch


【解决方案1】:

正如 cmets 中已经提到的:

  • 如果要将div 用作中缀函数,则必须将其括在反引号中
  • div 用于整数除法,向负无穷方向截断,而不用于除法Double

这两点是您的错误消息的原因。

要划分Doubles,请使用/ 运算符,就像您在表达式1/xn 中所做的那样。

有了这个你的代码应该可以工作。为了清楚起见,它可以被转换:

  1. 提取重复的表达式以计算序列中的下一个xnwhere 子句中。表达式也可以稍微简化。使用 cons 运算符 (:) 可以简单地在列表前添加单个元素:

    newtonRootSequence' xn d = xn' : newtonRootSequence' xn' d
        where xn' = (xn + (d / xn)) / 2
    
  2. 您可以使用 Prelude 中的 iterate :: (a -> a) -> a -> [a] 将单个步骤的计算与中间步骤列表的生成分开(注意翻转的参数):

    sequenceStep :: Double -> Double -> Double
    sequenceStep s xn = (xn + (s / xn)) / 2
    
    newtonRootSequence' :: Double -> Double -> [Double]
    newtonRootSequence' s x0 = iterate (sequenceStep s) x0
    

【讨论】:

    猜你喜欢
    • 2022-08-18
    • 2013-05-04
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多