2011-12-28 43 views
2

作爲一個練習,我試圖手動實現前奏的有趣部分。每當我發現一個機會去免費點我拿它。然而,這導致我在最不可能的地方出現了一堵磚牆。使用此代碼:試圖寫一個功能點免費,GHCI不批准

myelem _ [] = False 
myelem x y = if x == head y then True else myelem x (tail y) 

我試圖實施notElem。這裏是我的嘗試:

-- First 
mynotelem = not myelem 

由於類型不匹配,可以理解的爆炸。這很容易固定:

-- Second 
mynotelem x y = not (myelem x y) 

但是參數x和y的顯式聲明感到醜陋和不必要的,所以我儘量把它放回點自由風格。

-- Third 
mynotelem = not $ myelem 

從而未能與

Couldn't match expected type `Bool' 
     with actual type `a0 -> [a0] -> Bool' 
In the second argument of `($)', namely `myelem' 
In the expression: not $ myelem 
In an equation for `mynotelem': mynotelem = not $ myelem 

很公平,其種類仍然不匹配。但你如何解決它?再次您可以直接跳到

-- Fourth 
mynotelem x y = not $ myelem x y 

這是有效的,但似乎危險地接近剛剛進入圈子。我發現有可能消除其中一個論點:

-- Fifth 
mynotelem x = not . (myelem x) 

但是,討厭的x仍然存在。我如何消除它?

+2

ThelronKnuckle:如果你的避風港已經,搜索SO關於'($)'和'(。)'之間區別的問題 - 我想你會發現這些問題/答案很有幫助。 – 2011-12-28 02:36:42

回答

12

我們可以重寫你的代碼是這樣的:

mynotelem x = not . (myelem x) 
      = (not .) (myelem x) 

現在認識到,這僅僅是h x = f (g x)f = (not .)g = myelem,所以我們可以把它寫點自由與其他使用(.)運營商作爲h = f . g

mynotelem = (not .) . myelem 

注意圖案與多個參數的函數撰寫郵件時如何繼續:

> let f x y z = x+y+z 
> (((sqrt .) .) . f) 1 2 3 
2.449489742783178 

或者,你也可以用複合算這看起來很有趣的成分寫:

mynotelem = ((.).(.)) not myelem 

對於更多的參數,該模式將繼續是這樣的:

> ((.).(.).(.)) sqrt f 1 2 3 
2.449489742783178 
+3

無恥的插件,我上傳了「構圖」包hackage爲胸部操作員和朋友提供便利功能。 – 2011-12-28 08:42:26

+3

胸部操作員XD將pimping haskell用作我的伴侶時,必須將其用作優勢 – TheIronKnuckle 2012-02-03 00:08:55

+0

在實際代碼中使用「胸部操作員」是否很常見?處理這種情況的最簡潔的方法是什麼?如果只留下它的要點('mynotelem x = not. elem x'或'mynotelem x y = not $ elem x y')會更好嗎? – 2013-01-03 08:45:04