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

chr*_*ina 6 haskell list-comprehension

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

cubesLessThanN :: Int -> [Int]  
cubesLessThanN int = [if x * x * x <= int then x else * | x <- [0..int]]
Run Code Online (Sandbox Code Playgroud)

星号是我遇到问题的地方.一旦else发生,我有点想停止处理循环.决赛[list]应该只有立方体,而不是其他值x.我真的不在乎它是如何发生的,但想知道选项,以及差异是什么(如果有的话).

如果我尝试返回null,Nothing,'',和一些其他的.我知道int如果我退回任何东西,我应该返回一种类型.

Ry-*_*Ry- 11

用途takeWhile:

cubesLessThanN :: Int -> [Int]
cubesLessThanN int = takeWhile ((<= int) . (^3)) [0..]
Run Code Online (Sandbox Code Playgroud)

  • @chrisFrisina:不,但是你只能通过列表理解来做到这一点.您可以导致剩余的元素被排除,但这不是一回事(效率较低,不适用于无限列表).最接近的可能是`map fromJust $ takeWhile isJust $ [if x*x*x <= int then then just x else Nothing | x < - [0 ..]]`. (4认同)
  • 为了增加minitech的评论,列表推导只是到目前为止; 当你开始做更复杂的事情时,最好学会使用[`Data.List`]中提供的各种各样的东西(http://hackage.haskell.org/package/base-4.7.0.1/docs/ Data-List.html)库模块(如`takeWhile`). (2认同)

Jon*_*rdy 9

列表理解支持警卫.

[x | x <- [0..int], x ^ 3 <= int]
Run Code Online (Sandbox Code Playgroud)

由于列表推导是列表monad的糖,这相当于guarddo块中使用函数:

do
  x <- [0..int]
  guard (x ^ 3 <= int)
  return x
Run Code Online (Sandbox Code Playgroud)

如果我们将这个>>=和它内容定义为>>=guard:

concatMap (\x -> if x ^ 3 <= int then [x] else []) [0..int]
Run Code Online (Sandbox Code Playgroud)

这类似于过滤器.

filter (\x -> x ^ 3 <= int) [0..int]
Run Code Online (Sandbox Code Playgroud)

即使在值x ^ 3超过值之后,检查条件仍将继续(延迟)int.为了防止这种情况,您可以使用,takeWhile因为您知道您的功能是单调的.

takeWhile (\x -> x ^ 3 <= int) [0..int]
Run Code Online (Sandbox Code Playgroud)