How to break | break | return to understanding the Haskell list

I want to return all cubes (x ^ 3) that are smaller than the Int parameter, using list comprehension. I have the following:

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

An asterisk is where I have the problem. I want to stop loop processing as soon as else happens. The final [list] should only have cubes, not other x values. I don’t care how this happens, but I would like to know the options, and what are the differences (if any).

If I try to return null , Nothing , '' and several others. I know that I must return an int if I return anything at all.

+5
source share
3 answers

Mentioned listings support security devices.

 [x | x <- [0..int], x ^ 3 <= int] 

Since sugar is understood for monad lists, this is equivalent to using the guard function in the do block:

 do x <- [0..int] guard (x ^ 3 <= int) return x 

If we drop this at >>= and introduce the definitions >>= and guard :

 concatMap (\x -> if x ^ 3 <= int then [x] else []) [0..int] 

It looks like a filter.

 filter (\x -> x ^ 3 <= int) [0..int] 

The status check will continue (lazily) even after the value x ^ 3 exceeds the value int . To avoid this, you can use takeWhile because you know that your function is monotonous.

 takeWhile (\x -> x ^ 3 <= int) [0..int] 
+7
source

Use takeWhile :

 cubesLessThanN :: Int -> [Int] cubesLessThanN int = takeWhile ((<= int) . (^3)) [0..] 
+11
source

Take the cube root

 [ x ^ 3 | x <- [ 1 .. ceiling (fromIntegral int ** (1/3)) ], x ^ 3 < int ] 

For instance:

 Ξ» 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] 
+1
source

Source: https://habr.com/ru/post/1202386/


All Articles