2011-11-09 24 views
95

Có một lý do chính đáng tại sao loại Prelude.read làTại sao Prelude.read của Haskell không trả về một Có thể?

read :: Read a => String -> a 

hơn là trả lại một giá trị Maybe?

read :: Read a => String -> Maybe a 

Vì chuỗi có thể không phân tích cú pháp Haskell, liệu chuỗi này có thể tự nhiên hơn không?

Hoặc thậm chí là Either String a, trong đó Left sẽ chứa chuỗi gốc nếu nó không phân tích cú pháp và Right kết quả nếu nó đã làm?

Edit:

Tôi không cố gắng để có được những người khác để viết một wrapper tương ứng đối với tôi. Chỉ cần tìm kiếm sự bảo đảm rằng nó an toàn để làm như vậy.

+12

Tại sao không 'take' chấp nhận bất kỳ 'Num a => a'? Tại sao có một trường hợp đặc biệt của 'fmap' cho danh sách? Tại sao 'Functor' không được yêu cầu cho các cá thể' Monad'? Tôi hy vọng câu trả lời sẽ giống như câu trả lời cho những câu hỏi này và những câu hỏi liên quan. – delnan

+3

Vâng, đó là lý do tại sao tôi nói nó theo cách tôi đã làm, để lại các tùy chọn mở mà không có lý do chính đáng. Trong khi tôi cũng nghi ngờ có thể không có, giống như cho các ví dụ nổi tiếng bạn đưa ra, nó là giá trị yêu cầu để đảm bảo rằng viết wrapper của riêng tôi sẽ không tạo ra các vấn đề không lường trước được hạ lưu. –

+0

Tôi hy vọng một chức năng 'readMaybe' sẽ sớm được bổ sung. – augustss

Trả lời

93

Sửa: Tính đến GHC 7.6, readMaybe có sẵn trong thư viện Text.Read ở cơ sở, cùng với readEither: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Text-Read.html#v:readMaybe


Great câu hỏi! Các loại đọc chính nó không phải là thay đổi bất cứ lúc nào sớm bởi vì điều đó sẽ phá vỡ rất nhiều thứ. Tuy nhiên, có nên là một chức năng maybeRead.

Tại sao không có? Câu trả lời là "quán tính". Có một số discussion in '08 bị trật bánh bởi một cuộc thảo luận về "thất bại".

Tin tốt là mọi người đã đủ thuyết phục để bắt đầu di chuyển khỏi thất bại trong thư viện. Tin xấu là đề xuất đã bị mất trong trộn. Có nên là một hàm như vậy, mặc dù một hàm rất dễ viết (và có hàng tỷ các phiên bản rất giống nhau nổi xung quanh nhiều mã).

Xem thêm this discussion.

Cá nhân, tôi sử dụng phiên bản từ safe package.

26

Vâng, nó sẽ tiện dụng với chức năng đọc trả về Có thể. Bạn có thể làm một mình:

readMaybe :: (Read a) => String -> Maybe a 
readMaybe s = case reads s of 
       [(x, "")] -> Just x 
       _ -> Nothing 
+3

Cảm ơn bạn! Tôi hy vọng bản chỉnh sửa không có vẻ vô ơn! :) Chỉ muốn làm cho nó rõ ràng tôi không yêu cầu ra khỏi sự lười biếng ... –

+6

Nếu @augustss không thể cung cấp cho nó, một câu trả lời tốt hơn có thể không tồn tại. –

+2

Tôi không nghĩ rằng một phiên bản có thể đã từng được thảo luận trong thiết kế ban đầu. Nhiều người trong số những điều này trở nên rõ ràng với kinh nghiệm, nhưng có thể khó dự đoán. – augustss

14

Ngoài quán tính và/hoặc thay đổi những hiểu biết, một lý do khác có thể là nó thẩm mỹ để có một chức năng có thể hoạt động như một loại nghịch đảo của show. Nghĩa là, bạn muốn điều đó read . show là bản sắc (đối với loại trong nước là một thể hiện của ShowRead) và show . read là bản sắc trên phạm vi show (tức show . read . show == show)

Maybe trong các loại read phá vỡ đối xứng với show :: a -> String.

+0

Cảm ơn bạn đã thêm một góc mới! Điều đó có ý nghĩa. Nhưng để đạt được điều đó một cách rõ ràng, sẽ không có ý nghĩa gì khi có cả chương trình và đọc sản xuất một loại riêng biệt, nói "ParseableString"? –

+1

@BilalBarakat: Loại riêng biệt có thể là 'newtype ValidShow a = ValidShow String'. Kiểu ảo làm cho nó an toàn hơn. – yairchu

+7

Đó là một điểm thú vị, nhưng cuối cùng, một đối xứng sai. Các lập trình viên nên đánh giá đúng đắn về tính thẩm mỹ. –

11

Như @augustss đã chỉ ra, bạn có thể thực hiện chức năng đọc an toàn của riêng mình. Tuy nhiên, readMaybe của anh ấy không hoàn toàn phù hợp với đọc vì nó không bỏ qua khoảng trống ở cuối chuỗi.(Tôi đã phạm sai lầm này một lần, tôi không hoàn toàn nhớ bối cảnh này)

Nhìn vào definition of read in the Haskell 98 report, chúng tôi có thể sửa đổi nó để thực hiện một readMaybe hoàn toàn phù hợp với read và điều này không quá bất tiện vì tất cả các chức năng nó phụ thuộc vào được xác định trong Prelude:

readMaybe  :: (Read a) => String -> Maybe a 
readMaybe s  = case [x | (x,t) <- reads s, ("","") <- lex t] of 
         [x] -> Just x 
         _ -> Nothing 
+1

Cảm ơn! 1 để cảnh báo tôi về vấn đề khoảng trắng, mà trước đó chưa được làm rõ ràng. –

+3

Lưu ý rằng nếu bạn chỉ sử dụng gói 'safe', bạn sẽ nhận được phiên bản' readMaybe' chính xác (nó được gọi là 'readMay' và nó giống hệt với phiên bản này. –

6

Chức năng này (được gọi là readMaybe) hiện đang trong phần mở đầu của Haskell! (Theo cơ sở hiện tại - 4.6)

+2

Vâng, văn bản được liên kết nói nó nằm trong Text.Read chứ không phải trong Prelude (Có thể đã thay đổi), tuy nhiên, nó vẫn giúp tôi! – Kapichu

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