2013-04-18 23 views
9

Tôi đang học Haskell từ một thời gian ngắn, vì vậy tôi là một người mới.Các cuộc gọi đa hình Haskell không có kiến ​​thức kiểu hoàn chỉnh

Các mã sau đây là rất dễ hiểu:

purStrLn $ show [1] 

Ở đây chúng ta có thể suy ra tất cả các loại (với giá trị mặc định), và tất cả hoạt động tốt. Nhưng mã sau cũng hoạt động:

putStrLn $ show [] 

ngay cả khi chúng tôi không thể suy ra loại danh sách.

Nếu tôi thực thi mã với ghci tôi có được những điều sau:

Prelude> [] 
[] 
Prelude> :t it 
it :: [a] 
Prelude> 

nên loại có vẻ là đa hình. Nhưng trong trường hợp này, chương trình sẽ được gọi với một kiểu được áp dụng một phần.

Hành vi tương tự cũng phổ biến với các loại khác, ví dụ với Data.Map.empty, do đó, nó không phải là một tính năng danh sách (hoặc ít nhất nó có vẻ như nó).

Tại sao và cách thức hoạt động?

+0

'purStrLn $ chương trình [1] 'vẫn phải mặc một loại, như '[1] :: (Num n) => [n]' – amindfv

+0

Đó là sự thật, nhưng có mặc định trong trường hợp như thế này. – Totoro

+2

Lưu ý rằng điều gì đó khác xảy ra khi biến loại không bị giới hạn như trong ví dụ: 'length []', xem: http://stackoverflow.com/q/7076517. – hammar

Trả lời

16

Trước hết, tính năng này chỉ hoạt động trong ghci. Nếu bạn cố gắng để biên dịch chương trình này với ghc bạn sẽ nhận được một lỗi type:

Test.hs:3:19: 
    Ambiguous type variable `a0' in the constraint: 
     (Show a0) arising from a use of `show' 
    Probable fix: add a type signature that fixes these type variable(s) 
    In the second argument of `($)', namely `show []' 
    In the expression: putStrLn $ show [] 
    In an equation for `main': main = putStrLn $ show [] 

Thêm một chữ ký kiểu làm cho các lỗi đi:

module Main where 

main = putStrLn $ show ([]::[Int]) 

Nhưng tại sao nó hoạt động trong ghci? Câu trả lời là extended type defaulting trong ghci: loại a được mặc định là () (loại đơn vị).

Động lực cho hành vi này là nó hơi mệt mỏi một chút để người dùng luôn xác định các loại khi làm việc trong trình thông dịch. Như Vitus lưu ý trong các ý kiến, chạy ghci với -Wall (hoặc thêm :set -Wall-~/.ghci của bạn) làm cho nó dễ dàng hơn để phát hiện các sự mặc định:

<interactive>:2:12: 
    Warning: Defaulting the following constraint(s) to type `()' 
       (Show a0) arising from a use of `show' 
    In the second argument of `($)', namely `show []' 
    In a stmt of an interactive GHCi command: it <- putStrLn $ show [] 
+3

Ngoài ra, gõ ': set -Wall' trong GHCi giúp phát hiện ra giá trị mặc định này. – Vitus

+0

Tuyệt vời, đó là một câu trả lời rất giải thích :) – Totoro

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