2011-01-22 38 views
5

Vì vậy, tôi có một hàm với nhiều định nghĩa (bảo vệ), và tùy thuộc vào cái nào phù hợp, tôi đang cố gắng trả về (a, b) hoặc [ (a, b)], tuy nhiên trình biên dịch đang ném lên các lỗi vì chúng là các kiểu khác nhau. Tôi đã cố gắng sử dụng Hoặc để giải quyết điều này, nhưng có lẽ không sử dụng nó đúng: P. bất kỳ giúp đỡ?Làm thế nào để có một hàm trả về các kiểu khác nhau

+1

Bạn không thể làm điều đó trực tiếp vì loại trả về của hàm phải được biết tại thời gian biên dịch, trong khi các vệ sĩ được khớp vào thời gian chạy. Nhưng bạn có chắc chắn thực sự muốn trả lại một loại khác không? Nếu bạn có ý định kết hợp mẫu trên kết quả để phân biệt hai trường hợp, Hoặc là tốt. Hoặc có thể một danh sách singleton sẽ làm trong trường hợp đầu tiên? Bạn có thể cung cấp thêm chi tiết về những gì bạn định làm không? – b0fh

+0

http://paste.pocoo.org/show/325066/ là chức năng của tôi cho đến nay –

+0

giống như đọc phép thuật. Nó có nghĩa là gì? – luqui

Trả lời

9

Either - hoặc một kiểu dữ liệu tùy chỉnh tương đương với nó - là chỉ cách để làm điều này. Dưới đây là một ví dụ câm:

stuff :: Int -> Either (Int,Int) [(Int,Int)] 
stuff 0 = Left (0, 0) 
stuff n = Right [ (x,x) | x <- [0..n] ] 

Sau đó, khi ai đó gọi chức năng này, họ có thể đối sánh mẫu để tìm ra hai loại nó trả về:

foo n = case stuff n of 
      Left (a,b) -> ... 
      Right pairs -> ... 

Tuy nhiên, không biết gì về vấn đề của bạn, trong nói chung tôi muốn khuyên bạn nên suy nghĩ thêm một chút về ý nghĩa của chức năng của bạn. Nó sẽ làm gì, nó quay trở lại cái gì? Hãy chính xác, toán học. Câu trả lời đơn giản hơn, chức năng này sẽ hoạt động trơn tru hơn với phần còn lại của chương trình của bạn và các khái niệm về Haskell. Đối với tôi, trong các mô tả như vậy, Either hiếm khi xuất hiện. Làm thế nào bạn có thể thống nhất hai kết quả? Có thể bạn chỉ cần trả lại danh sách singleton [(a,b)] thay vì Left (a,b), nếu điều đó có ý nghĩa đối với chức năng của bạn.

Haskell không hoạt động tốt với các chức năng cố gắng quá thông minh, loại bạn có thể được sử dụng từ Python hoặc jQuery. Giữ nó câm và chính xác - làm cho sự phức tạp của bạn từ soạn những phần đơn giản này. Nếu bạn tò mò về điều này, hãy hỏi một câu hỏi khác với nhiều chi tiết hơn về vấn đề của bạn, những gì bạn đang cố gắng hoàn thành, và tại sao bạn muốn nó hoạt động theo cách đó. Xin lỗi cho việc rao giảng :-)

+0

Hãy để tôi thêm rằng thuộc tính chúng ta muốn của hệ thống kiểu là * bảo quản *: Nói một cách lỏng lẻo nếu chúng ta có kiểu 'stuff :: Int -> (Int, Int) 'sau đó một cuộc gọi đến' stuff 7' nói sẽ giảm xuống '[(x, x) | x <- [0..n] 'trong ví dụ có kiểu' [(Int, Int)] '. Điều này khác với loại trả về được công bố của 'nội dung' và do đó loại sẽ không được giữ nguyên.Nếu chúng ta tin tưởng vào hệ thống kiểu cho bất cứ điều gì, sự khác biệt này phải được loại trừ. Vì vậy, trình kiểm tra loại từ chối chương trình của chúng tôi là bị đánh máy. –

0

Các chức năng trong Haskell chỉ có thể trả về một loại do đó, hoặc sẽ hoạt động vì bạn sẽ có chức năng trả về loại (a, b) [(a.b)].

Tôi không chắc chắn những gì đã xảy ra với cách bạn đang sử dụng Hoặc nhưng đây là một ví dụ đơn giản của việc sử dụng của nó:

test a b = 
    if a == True 
    then Left (a,b) 
    else Right [(a,b)] 
+0

vì vậy, đây là chức năng của tôi ngay bây giờ: http://paste.pocoo.org/show/325090/ đây là lỗi: http: //paste.pocoo. org/show/325093/ –

+0

@Chris 'Phải lgst i' phải là' Phải (lgst i) '. – dave4420

+0

ok vì vậy http://paste.pocoo.org/show/325143/ hoạt động, tuy nhiên hai vệ sĩ sau cần phải tìm một cái gì đó như http://paste.pocoo.org/show/325144/ mang lại cho tôi: http://paste.pocoo.org/show/325145/ –

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