如何在Haskell列表理解中中断|返回

时间:2014-09-11 22:53:31

标签: haskell list-comprehension

我想使用列表推导返回小于参数Int的所有立方体(x ^ 3)。我有以下内容:

cubesLessThanN :: Int -> [Int]  
cubesLessThanN int = [if x * x * x <= int then x else * | x <- [0..int]]

星号是我遇到问题的地方。我有点想在else发生后停止处理循环。最终的[list]应该只包含多维数据集,而不是x的其他值。我真的不在乎它是如何发生的,但是想知道这些选项,以及它们之间的区别(如果有的话)。

如果我尝试返回nullNothing''和其他一些内容。我知道如果我退回任何东西,我应该返回int类型。

3 个答案:

答案 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]