Haskell'in Prelude.read'i neden Belki döndürmüyor?


108

Prelude.read türünün olmasının iyi bir nedeni var mı?

read :: Read a => String -> a

bir Maybedeğer döndürmek yerine ?

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

Dizi ayrıştırılabilir Haskell olamayacağına göre, ikincisi daha doğal olmaz mı?

Ya da Either String a, Leftayrıştırılmasa orijinal dizeyi nerede içerecek ve varsa Rightsonucu nerede olacak ?

Düzenle:

Başkalarının benim için karşılık gelen bir paketleyici yazmasını sağlamaya çalışmıyorum. Sadece bunu yapmanın güvenli olduğuna dair güvence arıyorum.


14
Neden hiçbirini takekabul etmiyor Num a => a? Neden fmaplisteler için özel bir durum var ? Örnekler Functoriçin neden gerekli değil Monad? Cevabın bunlara ve ilgili sorulara benzer olmasını bekliyorum.

3
İşte bu yüzden, iyi bir neden olmadığına dair seçeneği açık bırakarak bunu yaptığım şekilde ifade ettim. Verdiğiniz iyi bilinen örneklerde olduğu gibi olmayabileceğinden de şüpheleniyor olsam da, kendi paketleyicimi yazmanın aşağı yönde öngörülemeyen sorunlar yaratmayacağından emin olmak istemeye değer.
Bilal Barakat

Umarım readMaybeyakında bir fonksiyon eklenir.
augustss

İyi puan @delnan fakat olmamalıdır takeolmak Integral n => n -> [a] -> [a]?
Doug McClean

@DougMcClean: Evet, aslında olmalı Integral, Numbeyin osuruğu değil .

Yanıtlar:


106

Düzenleme : ghc 7.6 itibariyle readMaybemevcuttur Text.Readbirlikte, temel paketin modül readEither: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Text-Read.html#v: readMaybe


Harika soru! Okuma türünün kendisi yakın zamanda değişmeyecek çünkü bu pek çok şeyi bozacaktır. Ancak, bir işlev olmalıdırmaybeRead .

Neden yok Cevap "atalet" tir. Bir yoktu '08 tartışma üzerine bir tartışma ile raydan var "başarısız".

İyi haber şu ki, insanlar kütüphanelerde başarısızlıktan uzaklaşmaya başlamak için yeterince ikna olmuştu. Kötü haber ise teklifin karışıklıkta kaybolması. Orada gerektiğini bir yazma kolaydır (ve çevresinde birçok codebases yüzen çok benzer versiyonları katrilyonlar vardır) her ne kadar böyle bir fonksiyon olsun.

Ayrıca bu tartışmaya bakın .

Şahsen, güvenli paketin sürümünü kullanıyorum .


30

Evet, Belki döndüren bir okuma işleviyle kullanışlı olur. Kendin yapabilirsin:

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

3
Teşekkür ederim! Umarım düzenleme kulağa nankör gelmez! :) Sadece açıklığa kavuşturmak istiyorum Tembellikten sormuyorum ...
Bilal Barakat

6
@Augustss bunu sağlayamazsa, daha iyi bir yanıt olmayabilir.
John L

2
Orijinal tasarımda belki bir versiyonun tartışıldığını sanmıyorum. Bunların çoğu deneyimle aşikar hale gelir, ancak tahmin edilmesi zor olabilir.
ağustos

Nedeni bir liste döndürür okur birden fazla geçerli ayrıştırır yaşandığında içindir. Belki durumu, okuma ve okuma arasında orta düzeydedir.
Chris Kuklewicz

Sanırım bu Read atip sınıf gerektiriyor :readMaybe :: Read a => String -> Maybe a
David Tchepak

15

Eylemsizlik ve / veya değişen içgörüler dışında, bir başka neden estetik açıdan hoşa giden bir işleve sahip olmanın bir tür tersi işlevi görmesi olabilir show. Yani bunu istiyorsunread . show bunun kimlik olmasını ( Showve örneği olan türler için Read) ve bu (ie ) show . readaralığındaki kimlikshowshow . read . show == show

Bir Maybetürüne sahip olmak readsimetriyi bozar.show :: a -> String .


Yeni bir açı eklediğiniz için teşekkürler! Mantıklı. Ancak bunu temiz bir şekilde başarmak için, hem gösterme hem de okumanın ayrı bir tür üretmesi, örneğin "ParseableString" mantıklı olmaz mı?
Bilal Barakat

1
@BilalBarakat: Farklı tür olabilir newtype ValidShow a = ValidShow String. Fantom türü, onu daha güvenli hale getirir.
yairchu

9
İlginç bir nokta, ama nihayetinde yanlış bir simetri. Programcılar, estetiğin üzerinde doğruluğa değer vermelidir.
Matt Fenwick

1
@yairchu Fantom türü hakkında ne demek istediğini bana hemen belli etmedi, bu yüzden başkasının benim gibi kafası karışması durumunda açıklayacağım. Sen gibi bir şey niyetinde showThing :: Show a => a -> ValidShow ave readThing :: Read a => ValidShow a -> agösterilen şey tipi ValidShow nesnede hatırlanır böylece. Bu şekilde yazamazsın readThing (showThing True) :: String.
amalloy

12

@Augustss'ın da belirttiği gibi, kendi güvenli okuma işlevinizi yapabilirsiniz. Ancak, onunreadMaybe bir dizenin sonundaki boşlukları yok saymadığı için okuma ile tamamen tutarlı değildir. (Bu hatayı bir kez yaptım, içeriği tam olarak hatırlamıyorum)

Haskell 98 raporundaki okuma tanımına baktığımızda, onu readMaybemükemmel bir şekilde tutarlı olan a'yı uygulayacak şekilde değiştirebiliriz readve bu çok sakıncalı değildir çünkü bağlı olduğu tüm işlevler Prelude'de tanımlanmıştır:

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

1
Teşekkürler! Daha önce açıkça belirtilmemiş olan boşluk sorunu konusunda beni uyardığı için +1.
Bilal Barakat

3
Sadece safepaketi kullanırsanız, readMaybemevcut olanın doğru bir sürümünü elde edeceğinizi unutmayın (bu denir readMayve bu sürümle aynıdır.
Neil Mitchell

8

Bu işlev (çağrılan readMaybe) şimdi Haskell başlangıcında! (Mevcut tabana göre - 4.6)


2
Bağlantılı metin, metinde olduğunu söylüyor. Oku ve Prelude'da değil (değişmiş olabilir), ancak yine de bana yardımcı oldu!
Kapichu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.