2014-04-27 125 views
9

在Haskell中,是否可以在函數範圍內定義數據類型?Haskell:定義一個函數範圍的新數據類型

例如,我正在寫一個函數f :: [(Char, Int)] -> [(Char, String)]。在函數的實現中,我將從輸入列表構建一棵樹,然後遍歷樹來構建輸出列表。一種解決方案是定義一個特定於我的問題的新的Tree數據類型,以及兩個輔助函數,一個用於將輸入列表轉換爲樹,另一個用於遍歷Tree並構建輸出列表。

現在,通過將這兩個輔助函數放入where子句中,可以很容易地將它們拉入f的範圍,但是臨時nonce類型樹呢?通過在函數範圍之外定義它來污染名稱空間似乎很難,但我不知道要如何去做。

對於上下文,事實證明我正在計算霍夫曼編碼。在這一點上,我並不特別感興趣的是找到一種替代算法,因爲我懷疑它在Haskell中通常會在助手函數之間定義助手數據類型方面很有用,所以我對這種方法的一般方法感興趣。

+12

所有數據類型聲明都必須位於頂層。如果您不想污染名稱空間,則不要導出數據類型。 – user2407038

+0

[This](http://stackoverflow.com/questions/15320391/proposal-for-local-data-declarations-instances)可能是相關的。 – is7s

回答

6

不,這是不可能的。

在Haskell模塊和合格的導入應該解決所有的名稱空間問題,如你的或臭名昭着的記錄字段名稱衝突。

所以你想讓一個類型只對某個函數可見?將該類型和該函數放在一個新模塊中,並(可選)僅導出該函數。

當然,通過遵循這個約定,你將會得到比平常更多的模塊,但是如果你仔細想想,這與其他許多語言實際上並沒有什麼不同。例如,在Java中,將每個類放在一個單獨的文件中是常規的,不管這個類有多小。

我不得不提到,儘管離社區大多數人實際上都遵循這個約定。你經常可以看到用來解決這個問題的神祕名字。就我個人而言,我不覺得這樣的方法很乾淨,寧願推薦使用模塊。