我目前正在爲我的一個小項目編寫一些pipe-core/attoparsec管道。我希望每個解析器都提供一個管道,等待輸入到解析器的ByteString
並生成任何解析的值(重新啓動解析器)。如果沒有錯誤處理,它會因此有一個像使用管道(-core)進行錯誤處理的方法是什麼?
parserP :: Monad m => Parser a -> Pipe ByteString a m r
現在,我不確定如何處理解析錯誤。我現在的想法是:
- 的錯誤添加到返回類型
- 要求單子提供的錯誤處理機制(即
Either ParseError r
而不僅僅是r
返回一個值)(即要求單子的管被接管實現MonadError
) - 力單子通過接管
ErrorT e m a
所述管爲任何單子m
- 將參數添加到提供一個錯誤機構,讓用戶指定b ehaviour(像
(ParseError -> P.Pipe ByteString a m r)
,和簡單地結合到如此提供管在解析錯誤的情況下)
第一溶液似乎是錯誤的,如使用用於錯誤處理的管的返回類型似乎是相當一劈。首先,它使用管道醜陋構成組合,似乎或多或少被最終解決方案所包含(除了可能失去使下游管道能夠通過使用tryAwait從錯誤中恢復並停止等待值的能力?)。
第二種解決方案似乎是錯誤的,儘管我無法完全理解爲什麼。可能是因爲它可能(可能?)也需要將一個參數轉換成ParseError成爲Monad所具有的任何錯誤類型(除非我們希望要求monad實現MonadError ParseError
,這看起來會導致很多記錄)。最後,我似乎無法記住看到MonadError
這麼多,這表明使用它有一些問題。
第三種解決方案適用於我的情況,因爲管道將是用戶指定monad(IO)管道的一部分,不應該關心解析錯誤(它會將網絡數據解析爲格式屈服於用戶指定的類型)。但它似乎並不是那麼優雅,並且會再次(可能?)導致大量的書籍保留,一旦用於任何其他環境。
我還沒有真正想過最終的解決方案,但似乎有些複雜。
對於關於這個特殊情況的任何想法,我將不勝感激(如果我的方式不明確,我不會感到驚訝)以及任何(或多或少相關的)關於錯誤討論的參考在管道(核心)/管道/ interatee等處理
編輯: 另一種可能性是採取一次性動作(而不是一個完整的管道),儘管我不太確定它是否可能只是概括,專門化或甚至相當於第四個。
我會注意到建議3(使用'ErrorT e m a')完全被我個人最喜歡的建議2(使用'MonadError')包含。但我不確定如何對這個問題作出客觀的回答。 – 2012-07-10 08:37:58
我通過電子郵件發送了Gabriel通知他,因爲他是[管道](http://hackage.haskell.org/package/pipes)和[錯誤](http://hackage.haskell)的作者。 org/package/errors)包;據推測他一直在思考這兩件事情,可能在一起。 – 2012-07-10 10:14:36
@DanielWagner我同意它似乎是上述最好的解決方案。事情是,我總是引入額外的類型類;特別是對於任何不僅僅是運營商超載而言。 – 2012-07-10 10:57:32