我看到的大部分Haskell代碼都使用直接結構,如列表和樹。例如,它是很常見的Haskeller寫:Haskell中OCaml模塊的等價物是什麼?
fillRect :: Color → Bounds → Image → Image
這種模式有一個問題:假如以後程序員決定修改的「圖像」的定義,或使用其他數據結構,那麼他將必須重構使用它的每一段代碼。在OCaml中,您可以簡單地使用指定圖像接口的模塊,然後再決定具體的實現。
什麼是Haskell替代OCaml的模塊?
我看到的大部分Haskell代碼都使用直接結構,如列表和樹。例如,它是很常見的Haskeller寫:Haskell中OCaml模塊的等價物是什麼?
fillRect :: Color → Bounds → Image → Image
這種模式有一個問題:假如以後程序員決定修改的「圖像」的定義,或使用其他數據結構,那麼他將必須重構使用它的每一段代碼。在OCaml中,您可以簡單地使用指定圖像接口的模塊,然後再決定具體的實現。
什麼是Haskell替代OCaml的模塊?
有幾種選擇;沒有一個完全符合ML模塊,但每個方面都是。
參數多態性。關於Image
中的功能,請參數化Image
類型的 -constructor,而不是指定您的模塊和其中的fillRect
功能,而不是指定圖像的特定「種類」。所以這將是像
fillRect_ppm :: ImageImplemetation i => Colour -> Bounds -> Image i -> Image i
的簽名,其中ImageImplemetation
是某種類型的類,它指定類似的轉換和/或後端功能。
有了這樣的解決方案,你不能真的完全取代Image
類型,但你可以使類型本身任意靈活。很可能,您將用於Image
的所有具體類型實際上都會共享一些字段,因此最好不要使它比所需的更靈活:ImageImplemetation
的不同實例只需實現它們之間不同的不同的。如果這些實現非常相似,那麼您可能想要僅對像顏色空間這樣的細節進行參數化。
當然你需要提前計劃一下這個解決方案,但只是爲了一個通用的界面。如果你定義了必要的實例,你仍然可以在後面的任何類型作爲參數。
類似的(也可能混合),你可以只爲類型的類型類,它可以保存圖像數據。
fillRect_tcl :: Image img => Colour -> Bounds -> img -> img
的Image
類將直接定義一些像元如何畫線,並fillRect_tcl
將在其執行使用這些。好,因爲fillRect_tcl
立即與任何這樣的類型工作。有什麼不好的是,Image
類將需要相當笨拙(它的首選使用類型類的「數學」的東西與簡單和非常明確的法律)。
也許類甚至可以有矩形的方法:
class Image img where
...
fillRect_tcm :: Colour -> Bounds -> img -> img
...
不是很好的,你需要完全重新定義了任何img
實例方法。
Haskell的模塊系統不能做了很多,但仍然是有時不足以使你從保存重構一切。舉例來說,如果Image
從模塊Data.Image
來了,你可以做
import qualified Data.Image as IM
fillRect_qfi :: Colour -> Bounds -> IM.Image -> IM.Image
,並使用該模塊中定義的所有功能外,還通過預選賽。如果您在某個時候決定切換實施,則可以更改導入。
當然,這對轉換並不是很好,但是對於一次性更改而言確實很不錯。
很適合你的例子:diagrams同時使用第一點;例如rect使用TrailLike
類來實現其基元,並且該類包括類型爲QDiagram
的「最終」圖,該圖在您將用於渲染的後端進行參數化。
該類型簽名是如何表示'fillRect'使用(或者甚至可以訪問)'Image'類型的實現細節?你如何在OCaml中寫出不同的簽名(除了明顯的語法差異和不同的命名約定)? – sepp2k 2014-10-07 23:52:14
[這是Haskell模擬](http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/)。它不像Ocaml模塊那麼強大(至少不是沒有很多擴展),但它涵蓋了最常見的用例。只需在支持這些操作的類型上記錄多態函數。 – 2014-10-08 00:03:59
揹包是爲了將某種形式的模塊導入Haskell - http://plv.mpi-sws.org/backpack/ – nlucaroni 2014-10-08 13:45:18