2016-03-21 19 views
4

Haskell'e oldukça yeni geldim ve ilk projem, yakalanan WLAN paketlerini ayrıştırmak. Bu tür paketlerin ayrıştırılmasında ortak bir model, bir başlık alanının kalan baytların yapısını tanımlayacağıdır. Genel bir örnek olarak, bir paket böyle biçimlendirilebilir: başlığında bir bayrak alanı (bitmap olabilir) Ne yük (lar) ı belirlerHaskell'de ikili verilerin Monadic ayrışması

header + [payload A | payload B | ..] 

paket içinde yer almaktadır. Bu formatın belirli bir örneği için lütfen radiotap'a bakın.

A similar thread sadece bu gibi parse işlemler dizisi kullanımını önermektedir:

bu yük A ve B varlığı benim durumda uygulanamaz görünüyor Ancak
parseAll = do 
    hdr <- parseHeader 
    pa <- parsePayloadA 
    pb <- parsePayloadB 

başlığı ile tanımlanır. Diğer bir deyişle, veri ayrışmasının kontrol akışının önceden ayrıştırma sonucunu takip etmesi gerekmektedir. Bu tür bir modelle ikili veriyi ayrıştırmada genel bir yol varsa bunu anlamak isterim.

cevap

2

not edin. Monad'ların gücü tam olarak parsePayloadA ve parsePayloadB seçiminiz hdr'a bağlı olabilir: hdr'u denetlemek için Haskell'in tam gücüne sahipsiniz.

Yani temelde nedeniyle monadic bağlama türü özellikle bu güce sahip

parseAll = do 
    hdr <- parseHeader 
    payload <- case somethingInTheHdr hdr of 
     ThisIsAnA -> do 
     a <- parsePayloadA 
     return (PayloadA a) 
     ThisIsAB -> do 
     b <- parsePayloadB 
     return (PayloadB b) 
    -- can use body here, e.g. 
    return (Packet hdr payload) 

gibi bir şey yapabilirsiniz:

(>>=) :: m a -> (a -> m b) -> m b 

a -> m b ok, gerçek Haskell işlevi okunu olduğu vererek İhtiyacın olan tüm gücün var.

+0

Teşekkürler. Bu durumda "faydalı yük" türü ne olurdu? – liu3tao

+0

Bu, veri yükü = PayloadA A ile iki olası yükünüzün olduğunu varsayar. Yük B B' – Cactus

1

Bu tam olarak Monad arabiriminin amacıdır: bir hesaplamanın bağımlılığını bir önceki hesaplamanın sonucu olarak kodlamak. Senin durumunda

aşağıdaki gibi bir şey olacak: amaçlarınıza Ben bir anlayış almak için "Taste of State: Parsers are Easy" yazı okumanızı tavsiye için

parseAll = do 
    shouldThePayloadABeParsed <- parseHeader 
    if shouldThePayloadABeParsed 
    then do 
     pa <- parsePayloadA 
     ... 
    else do 
     pb <- parsePayloadB 
     ... 

nasıl Haskell eserlerini ayrıştırma bu tür ve "binary-parser" paket ayrıştırma yapmak. (do gösterim ve bağlar kullanımına görülebileceği gibi) parseAllmonadik ayrıştırıcı kütüphane bir tür kullandığı