2014-10-26 18 views
25

Phiên bản gần đây của ghc sẽ cảnh báo bạn nếu một chữ số nguyên nằm ngoài phạm vi của một loại nhất định. Ví dụ:Có loại số nguyên không dấu nào sẽ cảnh báo về các chữ cái âm?

$ ghci 
>>> let x = 330492039485 :: Data.Word.Word8 
<interactive>:2:9: Warning: 
    Literal 330492039485 is out of the GHC.Word.Word8 range 0..255 

Tuy nhiên, ghc sẽ không cảnh báo về literals số tiêu cực đối với Data.Word loại. Thay vào đó, nó underflows (cố ý, theo tài liệu):

>>> let x = -1 :: Data.Word.Word8 
>>> x 
255 

Có bất kỳ loại mà sẽ cảnh báo về literals tiêu cực hoặc là có cách nào tôi có thể tạo kiểu tùy chỉnh của riêng tôi mà không cảnh báo?

+0

Nhìn vào nguồn cho Data.Word, có vẻ như các cảnh báo được cài sẵn trong trình biên dịch. Có mô-đun 'Panic' trong gói ghc ẩn trông giống như nó có thể phát ra cảnh báo, nhưng điều đó không giống như một giải pháp rất tối ưu. – bheklilr

+0

Gần đây tôi đã muốn một hoặc hai 'phân nhóm' của Integer, cụ thể là Tự nhiên và Tích cực (và Tích cực là tùy chọn đối với tôi), lý tưởng nhất là sử dụng họ 'mpn_' trong GMP để thực hiện. Chúng tôi có 'Nat' ở cấp độ nhưng không có gì ở mức giá trị, và điều đó khiến tôi trở nên kỳ lạ, vì vậy tôi sẽ theo dõi các câu trả lời! – yatima2975

+3

Đối với câu hỏi của bạn, có một sự khác biệt để được thực hiện: không 'Word8' đại diện cho các số nguyên modulo 256 (trong trường hợp thực tế là' -1 == 255' là hoàn toàn hợp lý), hoặc là nó có nghĩa là đại diện cho tập hợp ' {0, ..., 255} '(trong trường hợp nào' -1 == 255' sẽ bị đánh máy)? Nó cũng liên kết với thiết kế lộn xộn 'Num'; '(-)', 'negate' và' fromInteger' không nên ở trong đó (hãy để một mình 'abs' và' signum'!), nhưng đó là một loại sâu khác ... – yatima2975

Trả lời

37

Theo mặc định, một chữ như số -1 được chia nhỏ thành negate (fromInteger 1). Tuy nhiên, có một tiện ích mở rộng ngôn ngữ NegativeLiterals làm cho tiện ích mở rộng ngôn ngữ đó trở thành desugar là fromInteger (-1). Nếu bạn kích hoạt mà bạn làm nhận được một cảnh báo:

Prelude> :m +Data.Word 
Prelude Data.Word> :set -W 
Prelude Data.Word> :set -XNegativeLiterals 
Prelude Data.Word> -1 :: Word 

<interactive>:74:1: Warning: 
    Literal -1 is out of the Word range 0..18446744073709551615 
18446744073709551615 
Prelude Data.Word> 

Ngoài ra, bạn có thể thực hiện kiểu của riêng bạn mà định nghĩa lại negate, nhưng sau đó bạn sẽ có lẽ chỉ nhận được một lỗi runtime.

+0

Cảm ơn! Điều này thật đúng với gì mà tôi đã tìm kiếm –

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