2015-06-15 34 views
1

我剛剛進入我的第一個真正的大小的Haskell項目(一個Web應用程序),並且我開始遇到來自第三方庫的類型泄漏問題的問題。下面是一個簡單的例子:在Haskell中處理來自第三方庫的數據類型的最佳實踐?

Parser模塊導入Test.Parsec和出口的函數(parseConfig)返回Either ParseError DbConfig,其中ParseError是在Parsec庫定義的數據類型(DbConfig是我的應用程序自定義數據類型,爲了簡潔起見未示出)。

-- Parser.hs 
module Parser where 

import Text.Parsec 

parseConfig :: String -> Either ParseError DbConfig 
parseConfig = parse ... 

後來,我想用我的parseConfig功能,但爲了使用它,我必須再次導入Text.Parsec讓我有機會獲得ParseError類型。

-- Api.hs 
module Api where 

import Parser 
import Text.Parsec 

getConfigFromBody :: Object -> Either ParseError DbConfig 
getConfigFromBody = parseConfig . (...) 

這不僅是一件麻煩事,只要進口管理雲,也有差的分離的擔憂,所以對的,我知道這是不是做到這一點的最好辦法蝙蝠。我的問題是,管理這個問題的最佳做法是什麼?製作一個類型的同義詞是否理想?

type ConfigParseError = ParseError 

parseConfig :: String -> Either ConfigParseError DbConfig 
parseConfig = parse ... 

這似乎是合理的,只要保持Parsec依賴內部到我的Parser模塊,但走樣庫類型似乎是一個奇怪的模式在默認情況下使用。

所以我的問題是,大型Haskell應用程序或庫如何處理?是否有通用的技術來管理來自第三方庫的數據類型?

回答

7

我不準備放棄的最佳做法,一個漂亮的列表,但對於初學者,如果你想保持的東西三立組織,使用明確的出口,而不是僅僅出口的一切,例如:

module Parser 
    (parseConfig 
) where 
... 

明確的出口量也允許您重新導出您的進口,例如

module Parser 
    (parseConfig 
    , ParseError(..) 
) where 
... 

後,你可以只import Parser,並有就好像是裏面Parser定義ParseError可用。

我認爲這應該解決您的直接問題。

+0

感謝您的回覆。所以這絕對有很多意義和幫助。它仍然感覺有點奇怪,主要是因爲我的模塊暴露了來自第三方模塊的數據類型。如果我想換出我的解析庫,理想情況下,我只需在解析器中更改它,而其他模塊不必關心甚至注意到這一變化。 – tydotg

+3

好吧,如果你想能夠交換解析庫,你不應該使用庫特定的ParseError作爲你的解析函數的輸出。如果你不使用它,那麼你的問題也將被解決,因爲沒有什麼可以再出口。 – zudov

+0

那麼這將是什麼樣子?意思是創建我自己的錯誤,捕獲任何'ParseError's,然後返回我自己的錯誤類型?我想這就是我首先想知道的 - 這是一種標準的做法嗎? – tydotg

相關問題