2011-02-11 14 views
7

IntMap üzerinde çalıştığım ve zorunlu olarak en iyi şekilde ifade edileceğini düşündüğüm bir algoritmam var. Yani, şöyle bir şey söylemek isterim:Data.Map/Data.IntMap için bir monad örneği var mı?

  • Haritadaki X değerini arayın.
  • Bir ölçütle eşleşiyorsa, bu değeri haritadan kaldırın.
  • Haritada daha fazla değer bulunana kadar döngü yapın.

Bu iki satırlık özyineleme olarak ifade etmek oldukça önemsiz olacaktır, ama gerçek algoritma birkaç aramaları ve silme içeren biraz daha karmaşıktır, bu yüzden do gösterimde bunu ifade edebilmek istiyorum .

do 
    insert 5 20 
    (ma, mv) <- lookup 4 
    case mv of 
    Just v -> delete (fromJust ma) 
    Nothing -> return() 

Dürüst ben en iyi bu nasıl ifade edeceğini emin değilim:

devlet ben böyle bir şey yapabilirim Data.Map veya Data.IntMap ile temsil edilir monad benzeri standart "Devlet" var mıdır. lookup nedeniyle bir tür MaybeT IntMap m yığından veya benzeri bir şeyden yararlanır.

Hatta var bildiğim kadarıyla insert ve delete işi yapma gibi, Data.IntMap dayalı kendi devlet monad tanımlamaya çalışmak biraz iş yapıldı ama lookup nasıl başa biraz sıkışmış var. Çoğunlukla bunun birisinin zaten çözdüğü bir şey olduğunu hissediyorum, ama bunu Hackage'da bulamıyorum. Mono trafolarını kullanmaktan kaçınmak için herhangi bir özel neden var mı?

cevap

21

Eğer Hackage gelen MaybeT paketi almak eğer böyle istediğini elde edebilirsiniz:

import Control.Monad 
import Control.Monad.Maybe 
import Control.Monad.State 
import qualified Data.Map as Map 

type MapM k v a = MaybeT (State (Map.Map k v)) a 

lookupM k = MaybeT $ Map.lookup k `liftM` get 
insertM k = modify . Map.insert k 
deleteM k = modify $ Map.delete k 

runMap m = (flip execState) m . runMaybeT 

foo = runMap Map.empty $ do 
    insertM 5 20 
    v <- lookupM 4 
    deleteM v 

lookupM hesaplama kalanı başarısız başarısız olduğunda. Bu monad'ları istediğiniz zaman girebilir ve kaçabilirsiniz, böylece bunları saf bir işlev ara yüzü altında gizleyebilirsiniz, yalnızca ana (ve güvenli olmayan işlevler kullanarak) dışında, dışarı çıkmayacağınız IO monad'sıdır.

Hatırlamanız gereken tek şey, geri dönen herhangi bir durum işlemidir. Belki de, MaybeT yapıcısına kaldırmanız yeterlidir. Eğer IO yapmak istiyorsanız Eyaleti StateT olarak değiştirin.

+0

Vay. Teşekkür ederim. Transformatörleri kullanmaya alışmam gerek. Bu örnek, bunları pratik olarak nasıl kullanacağınızı gösteren büyük bir yardımcıdır. Tüm manga öğreticiler size bir sıfırdan nasıl inşa edileceğini gösterir, ancak nadiren halihazırda mevcut olanı nasıl kullanacağınızı gösterirler. – Steve

+1

@Steve Monad transformatörlerini anlamamda bana yardımcı olan tek şey, onları bir monad yığını veya katmanları olan bir soğan yığını ve her monad transformer tipinin kayıt alanları veya çalışma fonksiyonları, aşağıdaki seviyeyi ortaya çıkarmak için bir katmanı çıkarır/soyar. –

İlgili konular