2015-06-04 19 views
5

Trong GHCi, tôi gõHaskell Danh sách Danh sách Loại Lỗi

let xs = [1, 'a'] 

nó phàn nàn lỗi ngay lập tức:

<interactive>:28:11: 
No instance for (Num Char) arising from the literal ‘1’ 
In the expression: 1 
In the expression: [1, 'a'] 
In an equation for ‘xs’: xs = [1, 'a'] 

Tuy nhiên, khi tôi gõ

let xs = [1, [1, 1]] 

Nó chỉ thông qua. Và nó phàn nàn khi tôi cố gắng in xs:

<interactive>:5:1: 
No instance for (Num [t0]) arising from a use of ‘it’ 
In a stmt of an interactive GHCi command: print it 

Tôi nghĩ Haskell là một ngôn ngữ kiểu tĩnh nên mọi lỗi phải được ghi trong thời gian biên dịch. Tôi tự hỏi tại sao 2 lỗi trên lại bị bắt vào thời điểm khác nhau?

Trả lời

8

1 là giá trị đa hình loại Num a => a. Vì vậy, trong [1, [2, 3]], chúng tôi có [2, 3] :: Num a => [a]; vì tất cả các phần tử danh sách phải có cùng một loại, chúng tôi kết luận rằng chúng ta phải có 1 :: Num a => [a]. Đó là một chút lạ - đó là lẻ để nghĩ về 1 như có một loại danh sách - nhưng có thể hoàn toàn hợp lệ nếu ai đó tạo ra một ví dụ đủ kỳ lạ của Num. Kiểm tra xem liệu một cá thể có tồn tại hay không được đẩy cho đến khi bạn cố gắng sử dụng cá thể; điều này cho bạn cơ hội để xác định cá thể sau khi bạn đã xác định giá trị bằng cách sử dụng cá thể. Vì vậy, nó không phàn nàn cho đến khi bạn cố gắng thực sự làm điều gì đó với danh sách [1, [2, 3]].

Chỉ để minh họa cho những gì tôi có nghĩa là, người ta có thể viết:

instance Num a => Num [a] where 
    fromInteger n = pure (fromInteger n) 
    (+) = liftA2 (+) 
    (-) = liftA2 (-) 
    (*) = liftA2 (*) 
    abs = liftA abs 
    signum = liftA signum 

(Trên thực tế, trường hợp này làm việc cho bất kỳ Applicative, và đôi khi thậm chí còn hữu ích.) Sau đó, trong ghci:

> let xs = [1, [1, 1]] 
> xs 
[[1],[1,1]] 

Xem ma, không có lỗi!

+3

Tại sao cùng một lý do không áp dụng cho trường hợp 'Num Char' tiềm năng? –

+0

@ReidBarton Câu hỏi hay! Tôi thực sự không chắc chắn về điều đó. Tôi đoán rằng trong thời gian giải quyết trường hợp, GHC từ chối trì hoãn việc tìm kiếm bằng chứng cho các ràng buộc đơn hình; nhưng đó chỉ là một phỏng đoán. –

+0

Bạn có thể định nghĩa một cá thể 'Num Char' dựa trên cá thể' Enum Char'. Cùng một lý do sẽ áp dụng, nhưng trường hợp chỉ không được bao gồm ở đây. –