低于任何给定非负小数的最大整数

时间:2017-05-15 11:35:06

标签: haskell recursion functional-programming tail-recursion

我怎么能使用尾递归,找到任何非负小数以下的最大整数?

我已经定义了函数largest :: Fractional f -> Int i但是在这种情况下看不出我如何使用尾递归。

1 个答案:

答案 0 :(得分:1)

任何Fractional都有类别定义,例如:

class Num a => Fractional a where
    fromRational :: Rational -> a
    -- ...

使用:

type Rational = Ratio Integer

(%) :: Integral a => a -> a -> Ratio a 

我还假设存在一个类型约束,以便我们可以比较两个fFractional实例)。所以我们能做的是:

  1. 首先将累加器设置为0
  2. 构建Rational,其值累加器+ 1
  3. Rational投射到f类型,
  4. 将构建的f与给定的f
  5. 进行比较
  6. 如果值大于给定值,则返回累加器
  7. 否则,我们通过递增的累加器执行递归。
  8. 所以在代码中看起来像这样:

    import Data.Ratio((%))
    
    largest :: (Fractional a, Ord a) => a -> Integer
    largest v = largest' 0
        where largest' x | fromRational (x1%1) >= v = x -- increment is less than or equal, return x
                         | otherwise = largest' x1 -- if smaller, recursion
                  where x1 = x+1 -- increment accumulator
    

    这给出了:

    *Main Data.Ratio> largest (7%5)
    1
    *Main Data.Ratio> largest (21%5)
    4
    *Main Data.Ratio> largest (1%5)
    0
    

    如果您想要更多关于返回类型的自由(任何Num,您可以在基础案例中添加fromIntegral

    import Data.Ratio((%))
    
    largest :: (Fractional a, Ord a, Num b) => a -> b
    largest v = largest' 0
        where largest' x | fromRational (x1%1) >= v = fromIntegral x -- increment is less than or equal, return x
                         | otherwise = largest' x1 -- if smaller, recursion
                  where x1 = x+1 -- increment accumulator