2012-08-26 10 views
5

Kullanıcı 1. giriş yaptığını kontrol ettiğim bir yetkilendirme planı oluşturmaya çalışıyorum 2. kullanıcının belirli bir nesneye erişimi var. Bunun için önce maybeAuthId numaralı telefonu arayın, sonra geçerli nesneyi almaya çalışın ve izinleri listeleyen başka bir tabloya 'katılın'. İki durumda belki de durumları ve bir seviye boş liste davası var. Ben, belki de T'yi kullanmayı düşündüm, ya da işe yaramamak için çok yoruldum ya da "gerçekten monad transformatörü olmayan" -handler-transformatörler, BelkiT ile kullanılamaz. Derin maymları idare etmenin güzel bir yolu var mı?Evetod ile yığın halinde yığın oluşturabilir

Düzenleme:

Ben öyle görünüyor biraz belli değildi. Ben böyle bir şey var anlamına geliyordu:

case foo of 
    Nothing -> something 
    Just foo' -> do 
     bar <- somethingelse 
     case bar of 
     Nothing -> ... 
     Just bar' -> ... 

cevap

6

Evetod için MaybeT'u tamamen kullanabilirsiniz. Sadece bu seversiniz:

runMaybeT $ do 
    uid <- MaybeT maybeAuthID 
    car <- MaybeT . runDB . getBy $ UniqueCarOwner uid 
    location <- MaybeT . liftIO . ciaLocateLicensePlate . licensePlate $ car 
    country <- MaybeT . findCountry $ location 
    return (car, country) 

Dediğiniz gibi, çoğu fonksiyonları Yesod'da genel hata işleme için optimize edilmemiştir. Ancak, Monad m => m (Maybe a) formunda bir şey varsa, Monad m => Maybe (m a) içine döndürmek için MaybeT kullanabilirsiniz. Anladığım kadarıyla

+0

Teşekkürler. Transformatörleri kullandığımdan beri bir süre geçti ve onları belki deTop'a sarmam gerektiğini unuttum. – Masse

1

Bu demek istediğini tam olarak net değil "idare derin maybes" tarafından, ancak bir anda iç içe bir düzeye çıkarmak monadic join (Control.Monad itibaren) kullanabilirsiniz.

ghci> :m +Control.Monad 
ghci> join (Just (Just 3)) 
Just 3 
ghci> join (Just Nothing) 
Nothing 
ghci> join Nothing 
Nothing 

BelkiTM kullanmak probleminiz için daha uygun olabilir. Ne yapmaya çalıştığını açıklığa kavuşturursanız, bunu BelkiT ile formüle etmenize yardımcı olabiliriz.

2

, senin katmanları gibi görünür:

Maybe [Maybe r] 

... ve iki Maybe birlikte s join istiyorum ama liste şekilde olduğunu. Biz Maybe monad için sequence uzmanlaşmak eğer almak

sequence :: (Monad m) => [m r] -> m [r] 

Not: En az varsa

Bu özel durumda
sequence :: [Maybe r] -> Maybe [r] 

, sequence bir Nothing dönecektir Bu tam sequence çözer sorunudur Listede bir Nothing, ancak hepsi Just s ise, o zaman hepsi tek bir Just içine katılacak. Yani

join . fmap sequence :: Maybe [Maybe r] -> Maybe [r] 

, sezgisel, yukarıda ne fonksiyonu:

fmap sequence :: Maybe [Maybe r] -> Maybe (Maybe [r]) 

Şimdi bu sebeple katılmak için gereken formda aynen geçerli:

Geriye kalan tek şey dış Maybe üzerinde sequence haritasına etmektir Tüm iç Maybe s Just s ve dış Maybe bir Just ise, o zaman, tüm sonucu içeren tek bir Just içinde birleştirir liste. Ancak, herhangi bir Maybe (iç veya dış olan) Nothing ise, son sonuç Nothing olur.

Dikkat edin ki, bir avuç kör tip takibine rağmen, doğru şeyi sezgisel olarak yapan bir işleve son verdik. Bu, kategori teorisine dayanan soyutlamaların gücüdür.