2011-07-16 29 views
6

Tôi đã bắt đầu thử nghiệm với Haskell và gặp sự cố. qqq là một hàm sẽ in một chuỗi nếu được gọi là "Không có gì" và in những thứ khác nếu được gọi với "Chỉ một cái gì đó".Sử dụng "Có thể" của Haskell, nhập khai báo [câu hỏi của người mới bắt đầu]

Các nỗ lực đầu tiên có vẻ như làm việc:

qqq Nothing = print "There isn't anything to be printed." 
qqq (Just x) = print "There is something to be printed." >> print x 

main :: IO() 
main = qqq (Just 43) 

Nhưng:

  • khi tôi cố gắng để làm cho main = qqq (Nothing) nó không thành công ("loại mơ hồ biến 'a0' trong chế: (Hiển thị a0) phát sinh từ việc sử dụng 'qqq' ")
  • Khi tôi muốn thêm chữ ký loại nếu không thành công:
    • qqq :: Maybe x => x -> IO() ->Type constructor 'Maybe' used as a class -> Nhưng phải không?
    • qqq :: (Maybe x) -> IO(). Bây giờ chữ ký chính nó trông giống như thành công. Nhưng main = qqq (Just 43) bắt đầu không thành công với lỗi (Show a0) bí ẩn như trong trường hợp main = qqq (Nothing).

Câu hỏi:

  1. Tại sao gọi QQQ với Nothing là quá khác biệt so với gọi với Just 43?
  2. (Show a0) là gì? Nó chỉ được đề cập trong các thông báo lỗi. Mọi nỗ lực để sử dụng nó dẫn đến một cái gì đó như "Hiển thị không trong phạm vi".
  3. Chữ ký loại chính xác cho điều này là gì? Làm thế nào để làm cho chữ ký loại in Haskell nó suy luận? Mong đợi một cái gì đó như:
f 0 = 2 
f x = (f (x-1)) + 3 

main = print get_type_as_string(f) 
-- prints "Number -> Number" 

Trả lời

9

Loại qqq là:

qqq :: Show a => Maybe a -> IO() 

Điều đó có nghĩa rằng qqq mất một tham số có kiểu Maybe a và trả về một hành động IO mà không có một giá trị, với sự ràng buộc rằng a triển khai Show kiểu chữ. Để tìm hiểu xem Show là gì, bạn có thể sử dụng :i Show trong ghci.

Show là công cụ đánh máy yêu cầu giá trị của loại có thể được chuyển đổi thành chuỗi. qqq có ràng buộc vì print muốn in giá trị (print có loại Show a => a -> IO()). Maybe không phải là typeclass mà là kiểu dữ liệu. Bạn có thể đọc thêm về typeclasses here.

Bạn có thể cho phép GHC suy ra chữ ký kiểu bằng cách nhập hàm vào tệp .hs, sau đó tải tệp bằng ghci (ghci Myfile.hs), sau đó nhập :t qqq để hiển thị loại.Bạn cũng có thể xác định hàm trong phiên tương tác với let qqq n = case n of { Nothing -> print "abc"; Just x -> print "def" >> print x } (có vẻ hơi khác một chút vì định nghĩa hàm phải nằm trên một dòng trong ghci, nhưng ý nghĩa là giống nhau).

Khi cuộc gọi chính qqq với qqq (Just 43), rõ ràng các loại bê tông của Maybe a là một loại số (giá trị mặc định ghci để Integer), do đó qqq có kiểu dữ liệu cụ của Maybe Integer -> IO(). Tuy nhiên, các cuộc gọi chính qqq với qqq Nothing, a có thể là bất kỳ thứ gì (không rõ ràng) và ghci báo cáo lỗi.

+0

Cũng trả lời câu hỏi không được hỏi "Tại sao tôi không thể đặt bất cứ điều gì trong ghci, nó than phiền' phân tích lỗi trên '=' '" –

+0

Là "loại mơ hồ" luôn luôn thất bại trong Haskell hoặc nó có thể quyết định "loại không quan trọng ở đây, vì vậy hãy để nó mơ hồ "đôi khi? –

+0

Haskell phàn nàn về các loại không rõ ràng khi trình biên dịch không biết phải làm gì. Vì vậy, nếu trình biên dịch có thể tìm ra loại nào sẽ không có vấn đề gì, nhưng nếu loại phải được suy ra mà không có đủ thông tin về nó thì bạn sẽ gặp lỗi. – Antti