2014-09-11 34 views
5

Tôi muốn trả về tất cả các khối (x^3) ít hơn một tham số Int bằng cách sử dụng một danh sách hiểu. Tôi có những điều sau đây:Làm thế nào để phá vỡ | phá vỡ | trở lại trong một danh sách Haskell hiểu

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

Dấu hoa thị là nơi tôi gặp sự cố. Tôi muốn ngừng xử lý vòng lặp khi xảy ra else. Cuối cùng [list] chỉ nên có các hình khối, không phải các giá trị khác của x. Tôi không quan tâm thực sự nó xảy ra như thế nào, nhưng muốn biết các lựa chọn, và sự khác biệt là gì (nếu có).

Nếu tôi cố gắng trả lại null, Nothing, '' và một số khác. Tôi biết tôi phải trả lại một loại int nếu tôi trả lại bất cứ thứ gì.

+0

có thể không sử dụng điều kiện hiểu danh sách? – Mephy

Trả lời

7

Danh sách comprehensions hỗ trợ lính gác.

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

Kể từ danh sách comprehensions là đường cho danh sách các đơn nguyên, điều này tương đương với việc sử dụng guard chức năng trong một khối do:

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

Nếu chúng ta desugar này vào >>= và nội tuyến các định nghĩa của >>=guard:

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

Đây là một phần của lọc er.

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

Kiểm tra tình trạng này sẽ tiếp tục (uể oải) thậm chí sau khi giá trị của x^3 vượt quá giá trị của int. Để ngăn chặn điều đó, bạn có thể sử dụng takeWhile vì bạn biết rằng chức năng của bạn là đơn điệu.

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

Sử dụng takeWhile:

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

Đây có phải là danh sách hiểu không? –

+4

@chrisFrisina: Không, nhưng bạn không thể làm điều đó chỉ với việc hiểu danh sách. Bạn có thể khiến các yếu tố còn lại bị loại trừ, nhưng đó không phải là điều tương tự (kém hiệu quả và không hoạt động trên danh sách vô hạn). Điều gần nhất có thể là 'map fromJust $ takeWhile isJust $ [nếu x * x * x <= int thì Just x else Nothing | x <- [0 ..]] '. – Ryan

+2

Để thêm vào nhận xét của minitech, việc hiểu danh sách chỉ đi xa đến vậy; khi bạn bắt đầu thực hiện những điều phức tạp hơn, tốt hơn là hãy học cách sử dụng nhiều thứ khác nhau được cung cấp trong [Data.List'] (http://hackage.haskell.org/package/base-4.7.0.1/docs/ Data-List.html) mô-đun thư viện (như 'takeWhile'). –

1

Hãy căn bậc ba

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

Ví dụ:

λ 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] 
+0

Điều này dẫn đến '[0,1,8,27]' cho cả '27' và' 64'. – Ryan

+0

minitech: cảm ơn, cố định. – rampion

+0

Bây giờ, nó sẽ bao gồm 1000 cho bất kỳ thứ gì trong (729, 1000). – Ryan

Các vấn đề liên quan