2011-05-06 57 views
15

鑑於Haskell中可以實現無點模式匹配?

data TwoInts = TwoInts Int Int 

add'em :: TwoInts -> Int 
add'em (TwoInts a b) = a+b 

是有可能寫add'em,而不必命名ab。喜歡的東西:

add'em TwoInts = (+) -- (Note: Fails to type check) 
+1

可能的:是的。明智的:不一定。 – 2011-05-06 20:41:23

回答

5

一般而言,我會說不,這是不可能的。但是,如果您試圖解決實際的問題(尤其是與newtypes共同),我經常會定義一個類似於fmap的mapf f (Type val) = Type (f val)函數,然後不導出它。你可以通過傳遞更多的函數來爲n元數據類型做同樣的事情。如果實現不應該是祕密的,也可以將其導出(作爲fmap for一元)。我推薦這種映射函數或複雜類型的視圖,因爲模式匹配會將您與實現聯繫起來。

基本類型已經定義了這樣的功能,例如, maybeeither

+0

爲什麼你說這是不可能的一般?您始終可以定義構造函數和解構函數來替換顯式模式匹配;並且你總是可以將一個尖的Haskell函數轉換成一個(任意複雜的)無點的版本。所以一般來說,它*是*可能的。 – 2011-05-06 23:10:49

+0

只是一個術語的東西,我以爲他在尋找一個不需要輔助函數的解決方案。即無點*模式匹配*。如果你定義了一個函數,那麼它是無點函數。破壞構造函數最終會歸結爲一個案例,對吧?我想你可以說幾乎所有泛型編程的東西意味着你不必寫一個case,但僅僅是因爲編譯器把一個放在自動Data實例中。 – 2011-05-07 04:52:54

+1

'maybe'和'either'實際上是對類型的摺疊(即使數據類型不是遞歸的,這可能是爲什麼它們不會被稱爲摺疊),因爲它將該類型的對象轉換爲其Church編碼:您提供它一個對應於每個構造函數的函數。要構建返回值,對這些函數的調用會將調用替換爲數據類型的構造函數。你的'mapf'與'fmap'非常相似,但只適用於一個帶有1個參數的構造函數;否則類比摺疊更有用。 – Blaisorblade 2011-07-23 16:19:41

12

通過類比元組,

data TwoInts = TwoInts { fst', snd' :: Int } 

我們可以定義爲吊裝的兩個參數的功能集成到一個TwoInt

uncurry' f p = f (fst' p) (snd' p) 

給我們很好的符號操作:

add'em = uncurry' (+) 
+0

好吧,現在我們只是把點移動到'uncurry'' – alternative 2011-05-06 19:41:07

+0

你甚至可以爲咖喱食物做一個類型的類,所以它可以應用到比TwoInts更多的地方... – pat 2011-05-06 19:42:50

+8

@mathepic,uncurry可以寫成pointfree。 'uncurry =('ap'snd)。 (.fst)'。關鍵是擺脫模式匹配。 – 2011-05-06 19:50:19