我想使用列表推导返回小于参数Int的所有立方体(x ^ 3)。我有以下内容:
cubesLessThanN :: Int -> [Int]
cubesLessThanN int = [if x * x * x <= int then x else * | x <- [0..int]]
星号是我遇到问题的地方。我有点想在else
发生后停止处理循环。最终的[list]
应该只包含多维数据集,而不是x
的其他值。我真的不在乎它是如何发生的,但是想知道这些选项,以及它们之间的区别(如果有的话)。
如果我尝试返回null
,Nothing
,''
和其他一些内容。我知道如果我退回任何东西,我应该返回int
类型。
答案 0 :(得分:11)
使用takeWhile
:
cubesLessThanN :: Int -> [Int]
cubesLessThanN int = takeWhile ((<= int) . (^3)) [0..]
答案 1 :(得分:9)
列表理解支持警卫。
[x | x <- [0..int], x ^ 3 <= int]
由于列表推导是列表monad的糖,这相当于在guard
块中使用do
函数:
do
x <- [0..int]
guard (x ^ 3 <= int)
return x
如果我们将此项目移至>>=
并内联>>=
和guard
的定义:
concatMap (\x -> if x ^ 3 <= int then [x] else []) [0..int]
这类似于过滤器。
filter (\x -> x ^ 3 <= int) [0..int]
即使x ^ 3
的值超过int
的值,检查条件仍将继续(延迟)。为了防止这种情况发生,您可以使用takeWhile
,因为您知道您的功能是单调的。
takeWhile (\x -> x ^ 3 <= int) [0..int]
答案 2 :(得分:1)
采用立方根
[ x ^ 3 | x <- [ 1 .. ceiling (fromIntegral int ** (1/3)) ], x ^ 3 < int ]
例如:
λ let int = 1000 in [ x ^ 3 | x <- [ 1 .. ceiling (fromIntegral int ** (1/3)) ], x ^ 3 < int ] :: [Int]
[1,8,27,64,125,216,343,512,729]