haskell中给定范围内所有偶数的平方列表

时间:2014-03-14 19:10:37

标签: haskell recursion

我需要返回给定范围内所有偶数的平方列表。所以功能是“正方形低”。输入和输出的示例将是正方形16 = [4,16,36]。到目前为止,我有这个,我认为我的逻辑是合理的,但由于我对Haskell很新,我不确定这里有什么问题,

    Squares low high = 
         let aux xxs low high
         | ([rem low 2] /= 0) = aux xxs (1 + low) high
         | ([rem low 2]==0) = aux ([low * low] ++ xxs) (1  + low) high
         | otherwise = xxs
         in aux [] low high

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:3)

Squares low high = -- ...

此行已被破坏,因为只有类型/模块可以以大写字母开头。

 let aux xxs low high
 | ([rem low 2] /= 0) = aux xxs (1 + low) high
 | ([rem low 2]==0) = aux ([low * low] ++ xxs) (1  + low) high
 | otherwise = xxs

aux会被叫多久?只有在点击otherwise时才会停止递归。但是整数是偶数或奇数,所以你永远不会返回xss。相反,您想要检查low > high

请注意,您可以在没有辅助功能的情况下定义squares

squares low high
  | low > high  = []
  | even low    = low*low : squares (low + 1) high
  | otherwise   = squares (low + 1) high

或使用mapfilter

squares low high = map (^2) . filter even $ [low..high]

或列表理解(基本上是mapfilter的语法糖):

squares low high = [x^2| x <- [low..high], even x]

答案 1 :(得分:1)

看起来你正在尝试做类似的事情:

squares :: Int -> Int -> [Int]
squares low high = aux [] low high
    where aux xxs low high
        | low > high = xxs
        | rem low 2 /= 0 = aux xxs (1 + low) high
        | otherwise = aux (xxs ++ [low * low]) (1  + low) high

你的警卫有几个原因是错误的。首先,[rem low 2][Int]而非Int,因此您需要删除括号。其次,由于前两个案例中的一个必须为真,因此永远不会达到otherwise条款。您应该将终止检查移至开头。

您也正在以错误的顺序构建输出列表 - 如果您想在结尾处使用下一个值,则在添加新元素时应使用xxs ++ [low * low]。请注意,使用++构建列表效率很低,最好使用(:)从前面添加元素。

最后,您可以使用mapfilter以更简单的方式执行此操作:

squares low high = map (\x -> x * x) . filter even $ [low .. high]

或列表理解:

squares low high = [x * x | x <- [low .. high], even x]

答案 2 :(得分:1)

生成从lowhigh的数字:

gen a b = a : gen (a+1) b

对吗?......不,错:它没有停止。我们可以添加停止条件吗?

gen a b | .....     = []
        | otherwise = a : gen (a+1) b

如果我们只想要偶数数字怎么办?

gen a b | .....            = []
        | rem ... ... == 0 = a : gen (a+1) b
        | otherwise        =     .....

很容易调整它来制作正方形。但我们真的需要测试我们自己产生的数字吗?如果a是偶数怎么办?

gen a b | even a = g a 
  where 
    g a | .....     = []
        | otherwise = a : g (a+2)    -- only evens are generated

如果它很奇怪怎么办?...