2014-08-31 30 views
4

我最近考試不及格,主要是因爲EDSL問題。我沒有掌握這些概念,所以我認爲這就是爲什麼我失敗了。我認爲我的老師的解釋是爲了讓我理解,所以我想知道有人能更清楚地解釋它。EDSL中的原始派生操作和組合器:s

我想知道是否有人能簡單地解釋一下EDSL的組成部分是什麼,以及它們的特徵。在我們的過程中,我們通過DSL的淺,深嵌入走了,看着下面積木的DSL:

  1. 構造函數
  2. 組合程序(原始的和衍生的)
  3. 運行功能

我認爲構造函數和運行函數更加明瞭,所以我更有興趣瞭解是什麼使得一個Combinator派生或原始。如果有人會解釋其他概念,這並不會受到傷害。這裏是我們講座的一個例子,以供參考。它的一個DSL的淺實行用於創建信號:

module Signal.Shallow 
(Time 
-- | the 'Signal' type is abstract 
, Signal 
-- * Smart constructors 
, constS, timeS 
-- * Combinators 
, ($$), mapT 
-- * Derived operation 
, mapS 
-- * Run function 
, sample 
) where 

-- * Smart constructors 
constS :: a -> Signal a 
timeS ::  Signal Time 
-- * Combinators 
($$) :: Signal (a -> b) -> Signal a -> Signal b 
mapT :: (Time -> Time) -> Signal a -> Signal a 
-- * Derived operation 
mapS :: (a -> b)  -> Signal a -> Signal b 
-- * Run function 
sample :: Signal a -> Time -> a 

type Time = Double 
newtype Signal a = Sig {unSig :: Time -> a} 

-- | The constant signal. 
constS x = Sig (const x) 

-- | The time signal 
timeS = Sig id 

-- | Function application lifted to signals. 
fs $$ xs = Sig (\t -> unSig fs t (unSig xs t)) 

回答

4

原語組合子是一種內置於所述DSL,在基本語言(即Haskell中)所定義。 DSL通常圍繞抽象類型構建 - 其實現對最終用戶隱藏的類型。這是完全不透明的。由語言呈現的原始組合器是那些需要知道抽象如何實際工作的人。

另一方面,派生的組合器可以用DSL中已有的其他組合器來實現。它不需要需要知道任何關於抽象類型。換句話說,派生的組合子是你自己寫的

這與Haskell本身的原始類型的想法非常相似。例如,您自己不能執行IntInt操作,如+。這些需要編譯器內置的東西才能工作,因爲數字是專門處理的。另一方面,Bool而不是原始;你可以把它寫成一個圖書館。

data Bool = True | False -- ... you can't do this for Int! 

DSL的「原始」和「派生」是相同的想法,除了編譯器實際上是你的Haskell庫。

在你的例子中,Signal是一個抽象類型。它作爲函數Time -> a實現,但該信息是從模塊導出的而不是。將來,您(作爲DSL的作者)可以自由改變如何實現Signal。 (而且,事實上,你真的想:這不是一個有效的表示,並使用Double時間是挑剔的。)

$$功能是原始的,因爲它依賴於知道SignalTime -> a。當您更改Signal的表示形式時,您必須重寫$$。此外,您的圖書館的用戶將無法自行實施$$

另一方面,mapS是派生操作,因爲它可以完全根據您要導出的其他內容編寫。它不需要知道任何關於Signal的特殊內容,甚至可以由圖書館的其中一個用戶編寫。實現可能看起來像:

mapS f signal = constS f $$ signal 

注意它如何使用constS$$,但從來沒有解開signal的知識如何去展開信號完全隱藏在這兩個函數中。 mapS是「派生的」,因爲它只寫在你的DSL中,而不需要任何低於抽象級別的東西。當您更改Signal的實施時,mapS仍然可以正常工作:您只需更新constS$$,並且您可以免費獲得mapS

因此:原始組合器是直接構建到您的語言並需要了解其內部實現細節的原始組合器。派生的組合器純粹用的語言編寫,並且不依賴於任何這些內部細節。它們只是便利功能,可以很容易地由您的圖書館的最終用戶編寫。

+1

很好的解釋。謝謝! – patriques 2014-08-31 17:09:30