我需要返回给定范围内所有偶数的平方列表。所以功能是“正方形低”。输入和输出的示例将是正方形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
任何帮助都将不胜感激。
答案 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
或使用map
和filter
:
squares low high = map (^2) . filter even $ [low..high]
或列表理解(基本上是map
和filter
的语法糖):
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]
。请注意,使用++
构建列表效率很低,最好使用(:)
从前面添加元素。
最后,您可以使用map
和filter
以更简单的方式执行此操作:
squares low high = map (\x -> x * x) . filter even $ [low .. high]
或列表理解:
squares low high = [x * x | x <- [low .. high], even x]
答案 2 :(得分:1)
生成从low
到high
的数字:
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
如果它很奇怪怎么办?...