2010-06-13 44 views
10

anda buHaskell haritaları

lookup :: (Monad m, Ord k) => k -> Map k a -> m a 
daha genel türü için kullanılan

lookup :: Ord k => k -> Map k a -> Maybe a 

tür imzası ile Belki sarılı değerleri döndürür Data.Map ve Data.IntMap içinde arama fonksiyonu

Birincisi, muhtemelen ekstra tip belirtimi ihtiyacını azalttığını farkettim, ancak ikincisi onu çok daha genel hale getirecek ve liste kavramalarında arama yapılmasına izin verecektir. Bu davranışı daha yeni sürümle taklit etmenin bir yolu var mı, yoksa kütüphanenin eski bir sürümünü mi kullanmalıyım? tek hücreli sınıfları çoğunluğu error olarak başarısız tanımlamak olarak

cevap

5

Don lift genel Monad muadillerine Maybe 'ın elemanları dönüştürür, böylece sadece liste comprehensions ve diğer monads ağırlıklı lookup kullanmak istiyorsanız belki convert veya generalize falan ;-)

adlı olmalıdır

 
Prelude> [ v | Just v <- return $ lookup "hi" [("ho","silver")] ] 
[] 
Prelude> [ v | Just v <- return $ lookup "ho" [("ho","silver")] ] 
["silver"] 

Prelude> do Just v <- return $ lookup "hi" [("ho","silver")] ; print v 
*** Exception: user error (Pattern match failure in do expression at <interactive>:1:3-8) 
Prelude> do Just v <- return $ lookup "ho" [("ho","silver")] ; print v 
"silver" 
+1

Bu, başarısızlık kullanımının neden kötüye kullanıldığını mükemmel bir şekilde gösterir: neredeyse her zaman bir program sonlandırması istisnasıdır. Haritalara bakarken istediğin şey değil. –

+0

Şey, "başarısızlığı uygulayan monadlar" dedim, değil mi? -) 'error' undefined uygulanmadı. Ben de bu davayı açıklamak istedim. Şahsen ben de monad bir 'MonadPlus' olduğunda ve 'mzero' olarak 'başarısız' uygularsa, bloklar halinde desen eşleşmesi başarısızlığı kullanıyorum. Bu tekniğin en kullanışlı olduğu zamandır. – claus

19

ikinci, çok daha genel ve daha güvenli da arama listesi comprehensions

ikinci kullanılmak üzere izin verir. Yani, Harita'da bir eleman bulamaması, çoğu monad için bir program sonlandırma hatasıdır. Bu, yanlış tip bağlamın çıkma olasılığının bir araya gelmesiyle birleştiğinde, şimdi 'monadik başarısızlık geri dönüşü' stilini cesaretlendirmek anlamına geliyor.

Nitekim orada daha yeni bir sürümü ile bu davranışı taklit etmek için bir yolu var mı! örneğin

lift :: Monad m => Maybe a -> m a 
lift Nothing = fail "you die now" 
lift (Just a) = return a 

Ve şimdi yazabilir: Sadece şöyle, Monad içine Belki bir asansör lift . lookup

+0

Teşekkür hızlı cevap Don için: Liste monadın e, basit çözüm maybeToList kullanmaktır. Bu, ortaya çıktığımdan çok daha özlü. – sabauma

+0

Bir sonraki ana sürümün çıkmasıyla bu cevabı güncellemeyi düşünmek mantıklı olabilir. 'Başarısızlık' nihayetinde 'Monad' bırakarak, belki de yeni bir 'MonadFail' 'inişine benziyor. – dfeuer

4

belirli cas için: o da fail için kalıp eşleştirme başarısızlık haritalama yararlanabilecek bir fail uygulamak

Prelude> :m +Data.Maybe -- Note: Use "import Data.Maybe" in a program file 

Data.Maybe> [ v | v <- maybeToList $ lookup "hi" [("ho","silver")] ] 
[] 
Data.Maybe> [ v | v <- maybeToList $ lookup "ho" [("ho","silver")] ] 
["silver"]