Haskell - 期望的类型与实际类型

 美煤MM就 发布于 2023-02-12 23:58

我已经定义了以下功能:

calculateApproximation :: Int -> Int -> Int -> Double -> Double
calculateApproximation n a r tol =
  if abs(((take n xs)!!(n-1)) - (((take n xs)!!(n-2)))) <= tol
    then ((take n xs)!!(n-1))
    else calculateApproximation (n+1) a r tol
  where xs = unfoldr (\x -> Just(x, (x + (r/x))/2)) a

但我看到以下类型错误:

Couldn't match expected type `Int' with actual type `Double'
    In the second argument of `(<=)', namely `tol'
    In the expression:
      abs (((take n xs) !! (n - 1)) - (((take n xs) !! (n - 2)))) <= tol

但是tol,当我已经将它定义为Double时,它为什么期望成为Int?或者我在这里忽略了一个完全愚蠢的错误?

1 个回答
  • 最简单的解决方法是修改类型签名,以便您的初始猜测a和计算平方根的r数字Double而不是Int.

    我也冒昧地将定义分解出来ys = take n xs以简化代码.

    calculateApproximation :: Int -> Double -> Double -> Double -> Double
    calculateApproximation n a r tol =
        if abs (ys!!(n-1) - ys!!(n-2)) <= tol
          then ys!!(n-1)
          else calculateApproximation (n+1) a r tol
        where xs = unfoldr (\x -> Just(x, (x + (r/x))/2)) a
              ys = take n xs
    

    但是,正如在注释中指出的那样,n在查找n-1第th个元素之前,实际上并不需要获取元素.您可以申请!!无限列表,这可以进一步简化您的代码

    calculateApproximation :: Int -> Double -> Double -> Double -> Double
    calculateApproximation n a r tol =
        if abs (xs!!(n-1) - xs!!(n-2)) <= tol
            then xs!!(n-1)
            else calculateApproximation (n+1) a r tol
        where xs = unfoldr (\x -> Just(x, (x + (r/x))/2)) a
    

    为了清晰起见,我可能会考虑更多的定义

    calculateApproximation' n a r tol = go n
      where
        go n = let eps = abs $ xs!!(n-1) - xs!!(n-2)
                in if eps <= tol
                    then xs !! (n-1)
                    else go (n+1)
    
        xs = unfoldr (\x -> Just (x, (x + r/x)/2)) a
    

    最后,我会发现操作go永远只使用n-1n-2列表的元素,从来没有前面的元素,该指数n仅用于跟踪您在列表中的位置.所以我会重写,以便go在列表上操作,而不是在索引上操作,并让它遍历列表,直到找到合适的答案.而在一个较小的整洁行动,我会从改变unfoldriterate-你只有真正想unfoldr如果列表应该在某个点终止.

    calculateApproximation a r tol = go xs
      where
        go (x:y:rest) = if abs (x-y) < tol
            then y
            else go (y:rest)
    
        xs = iterate (\x -> (x+r/x)/2) a
    

    2023-02-13 00:40 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有