2017-08-24 48 views
2

我正在開發一個程序,我需要從USB連接解析數據並將其寫入循環緩衝區。Conduit解析器被提前中斷

我一直遇到的問題是解析器沒有使用輸入。我是否需要使用另一個操作員將解析器管道連接到ByteString s流?

如果我刪除了兩個'過濾器'dropCdropWhileC,解析器會消耗一些輸入,但會失敗,因爲前幾個數據塊是垃圾。不知何故(我從來沒有用過它)顯然我的心理模型是如何運作的。

我也想知道空字符串是否被conduitParser視爲EOF標記,就像attoparsec自己的parseWith一樣。

-- | 
sourcePort :: SerialPort -> Producer IO ByteString 
sourcePort port = repeatMC (recv port 16) 


-- | 
parseSerialStream :: (Vector v (Int, Int)) => RingBuffer v (Int, Int) -> SerialPort -> IO() -- ConduitM a c IO() 
parseSerialStream buffer port = sourcePort port 
          .| dropC 4 
          .| dropWhileC B.null 
          .| conduitParser (parseMeasurement <* endOfLine) 
          $$ mapM_C (\item -> print item >> RB.append (snd item) buffer) 
+0

做'sourcePort端口。 dropC 4 >> dropWhileC B.null >> conduitParser(parseMeasurement <* endOfLine)$$ .....'工作? – danidiaz

+0

不幸的是:'無法將類型\'ByteString'與\'()'進行匹配' – SwiftsNamesake

+1

圓括號怎麼樣,比如'sourcePort port。 (dropC 4 >> dropWhileC B.null >> conduitParser(parseMeasurement <* endOfLine))$$ .....' – danidiaz

回答

2

@danidiaz已經在評論認爲dropC解釋等人不要產生任何值,這就是爲什麼你必須使用monadic組合而不是管道(.|)。

對於任何人都會遇到這個問題,詳見this answer

此代碼按預期工作:

parseSerialStream :: RingBuffer VU.Vector (Int, Int) -> SerialPort -> IO() -- ConduitM a c IO() 
parseSerialStream buffer port = sourcePort port 
          .| (dropC 4 
          >> dropWhileC B.null 
          >> conduitParser (parseMeasurement <* endOfLine)) 
          $$ mapM_C (\item -> RB.append (snd item) buffer) 

我喜歡管雖然是什麼樣子。呵呵......

+0

Pinging @MichaelSnoyman – SwiftsNamesake