2010-07-30 34 views
15

Tôi có một chức năng mà có một kiểu trả về của Maybe ([(Int,Int)],(Int,Int))Hoạt động trên một trở về từ một lẽ có chứa "Chỉ"

Tôi muốn gọi đây là từ chức năng khác và thực hiện một thao tác trên dữ liệu.

Tuy nhiên, giá trị trả về nằm trong phạm vi Just. Phương pháp thứ hai mất ([(Int,Int)],(Int,Int)) và do đó sẽ không chấp nhận Just ([(Int,Int)],(Int,Int)).

Có cách nào tôi có thể cắt Just trước khi áp dụng phương pháp thứ hai không?

Tôi không hiểu rõ việc sử dụng Just trong vòng Maybe - tuy nhiên, tôi đã được thông báo rằng loại trả lại cho Phương thức đầu tiên phải là Maybe.

+0

lẽ được sử dụng nếu không chắc chắn của bạn về loại giá trị trả về. Ví dụ, phương thức của bạn có thể trả về một chuỗi lỗi. –

+7

@ Jonathan Fischoff: Có thể là * không * được sử dụng nếu bạn không chắc chắn về loại đó. Không có cách nào phương thức trả về 'Có thể ([(Int, Int)], (Int, Int))' có thể trả về một chuỗi lỗi. Có thể được sử dụng khi bạn không biết nếu bạn sẽ có một giá trị để trả lại hay không, vì vậy bạn có thể trở lại Chỉ là giá trị hoặc Không có gì. – Chuck

+0

@Jonathan Fischoff: Một phần chính xác. Bạn sử dụng Có thể khi không có kết quả (Không có gì), ví dụ: getPosition :: List a -> Maybe Integer'. Bạn sử dụng 'Either' để trả về một trong hai (không có ý định chơi chữ) một giá trị trả về hợp lệ (Phải) hoặc lỗi (Trái). Chỉnh sửa: @Chuck nhanh hơn. – delnan

Trả lời

6

Bạn đang tìm kiếm fromJust. Nhưng chỉ khi bạn đang nhất định chức năng Maybe của bạn sẽ không trả lại số Nothing!

+0

Cảm ơn bạn, điều đó sẽ thực hiện. Nó luôn luôn trả về một giá trị khi được gọi từ phương pháp này bởi vì tôi chỉ tái chế một phương pháp được viết cho một cái gì đó khác. – KeepItFoolish

+11

từJust được coi là hình thức xấu trong Haskell - như là bất kỳ chức năng một phần như 'đầu'. Tôi sẽ giới thiệu một trong hai lựa chọn thay thế trong câu trả lời của TomMD. – luqui

46

Có một số giải pháp cho vấn đề của bạn, tất cả đều dựa trên kết hợp mẫu. Tôi giả sử bạn có hai thuật toán (vì bạn không nêu rõ tên họ, tôi sẽ):

algorithm1 :: a -> Maybe b 
algorithm2 :: b -> c 
input :: a 

1) Pattern matching thường được thực hiện từ một trong hai một tuyên bố trường hợp (dưới đây) hoặc một hàm.

let val = algorithm1 input 
in case val of 
    Nothing -> defaultValue 
    Just x -> algorithm2 x 

Tất cả các giải pháp được trình bày khác sử dụng đối sánh mẫu, tôi chỉ trình bày các chức năng chuẩn thực hiện mẫu phù hợp với bạn.

2) Bản mở đầu (và Data.Maybe) có một số hàm tích hợp để xử lý Maybe s. Các chức năng maybe là một trong những tuyệt vời, tôi đề nghị bạn sử dụng nó. Nó được định nghĩa trong thư viện chuẩn như:

maybe :: c -> (b -> c) -> Maybe b -> c 
maybe n _ Nothing = n 
maybe _ f (Just x) = f x 

Mã của bạn sẽ trông như thế:

maybe defaultValue algorithm2 (algorithm1 input) 

3) Kể từ khi lẽ là một functor bạn có thể sử dụng fmap. Điều này có ý nghĩa hơn nếu bạn không có giá trị mặc định. Định nghĩa:

instance Functor Maybe where 
    fmap _ Nothing  = Nothing 
    fmap f (Just a)  = Just (f a) 

Vì vậy, mã của bạn sẽ trông như thế:

fmap algorithm2 (algorithm1 input) 

Kết quả này sẽ là một giá trị Maybe (Nothing nếu kết quả của algorithm1 là Nothing).

4) Cuối cùng, và không khuyến khích mạnh mẽ, là fromJust. Chỉ sử dụng nó nếu bạn dương, thuật toán đầu tiên sẽ trả về Just x (và không phải Nothing). Hãy cẩn thận! Nếu bạn gọi fromJust val khi val = Nothing thì bạn sẽ nhận được ngoại lệ, điều này không được đánh giá cao trong Haskell.định nghĩa của nó:

fromJust   :: Maybe b -> b 
fromJust Nothing = error "Maybe.fromJust: Nothing" -- yuck 
fromJust (Just x) = x 

Rời mã của bạn để trông giống như:

algorithm2 (fromJust (algorithm1 input)) 
+3

Tôi đặt nó theo một cách khác: kết hợp mẫu là cách kinh điển để đối phó với kết quả 'Có thể', những cái khác chỉ là chữ viết tắt cho các cách phổ biến để làm điều đó. (Vì OP có lẽ không biết chúng, tôi cũng nêu rõ các định nghĩa của chúng.) –

+0

Điểm tốt. Nhìn lại, tôi nghĩ rằng tôi bắt đầu với 'fromJust' chỉ vì đó là câu trả lời đã được đưa ra và được chấp nhận bởi người hỏi. –

+0

Mặc dù 'yuck', tôi tìm thấy từChỉ cần cách dễ nhất để hiểu điều này. Cảm ơn câu trả lời của bạn trong mọi trường hợp. – vikingsteve

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