2017-05-17 103 views
1

Haskell中可能有兩個具有相同名稱的函數具有不同數量的參數嗎?這就是我想做的事:重載Haskell函數以具有不同數量的參數

inc = (+) 1

inc x = (+) x

我希望能夠到默認調用我的增值功能不帶參數的遞增1,或者用一個參數,並把它遞增由x。

的我可以做以下任一,例如:

map(inc)[1,2,3] --results在[2,3,4]

map(inc 2)[1,2,3] - 結果[3,4,5]

+1

你可以通過類型類有多個參數的功能,有點欺騙,例如見Development.Shake.cmd。雖然我想添加一個免責聲明 - 這不是初學者的東西,更多的是一箇中間話題 – epsilonhalbe

+6

作爲另一個免責聲明 - 即使在技術上可行的情況下,Haskell開發者也不是這樣做的,因爲它干擾了部分應用程序,我們一直使用*。這也是一種痛苦。 – luqui

+0

另請參閱:[增量式特設參數抽象](https://byorgey.wordpress.com/2010/04/03/haskell-anti-pattern-incremental-ad-hoc-parameter-abstraction/)。 –

回答

6

首先,簡單的辦法是隻取了這個Maybe 「默認參數」:

inc :: Num a => Maybe a -> a -> a 
inc Nothing x = 1 + x 
inc (Just i) x = i + x 

否則,是的,這是可能的,但它可能不值得。該技術是爲類型類型創建一個具體類型(操作結果)和函數(接受更多參數)的實例。

介紹之類的類型,可以作爲一個增量的結果:

class Inc i where 
    inc :: Integer -> i 

如果呼叫者需要一個整數,我們增加一個:

instance Inc Integer where 
    inc = (+) 1 

如果來電者的需求一個返回整數的函數,我們通過該函數的參數遞增:

instance (Integral a) => Inc (a -> Integer) where 
    inc x = (+) x . toInteger 

N這些流量都工作:

map inc [1, 2, 3] 
map (inc 2) [1, 2, 3] :: [Integer] 

但需要類型標註除非結果由使用結果的東西限制爲[Integer]。如果您嘗試使用泛型類型,如Num a => a,而不是具體的Integer,或者如果你把它用一個(Integral a, Inc i) => Inc (a -> i)更換實例(Integral a) => Inc (a -> Integer)接受任何數量的參數類型推斷變得更糟糕。另一方面,您也可以爲其他具體類型添加實例,例如IntDouble

我想我的反問題是:你實際上試圖解決什麼問題?

1

不,這是不可能的。在Haskell中,函數的最新定義具有優先權。所以,如果你定義INC的兩個版本:

inc = (+) 1 
inc x = (+) x 

然後第二個定義將陰影的第一個定義。這意味着如果你調用「inc」,現在將使用第二個定義。

然而,你仍然可以完成你想要的部分應用程序。 如果你讓你的2個電話curried它會有同樣的效果。像這樣:

map (inc 1) [1,2,3] 

返回[2,3,4]

map (inc 2) [1,2,3] 

返回[3,4,5]