簡體   English   中英

重載Haskell函數以具有不同數量的參數

[英]Overloading Haskell functions to have different number of arguments

是否有可能在Haskell中有兩個相同名稱的函數具有不同數量的參數? 這就是我想要做的:

inc = (+) 1

inc x = (+) x

我想能夠調用我的增量函數,沒有參數,默認增加1,或者使用參數,並使其增加x。

我可以做以下任何一種,例如:

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

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

首先,簡單的替代方法就是為這種“默認參數”選擇一個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

現在這兩個都有效:

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

但是類型注釋是必需的,除非結果被使用結果的東西約束為[Integer] 如果您嘗試使用泛型類型(如Num a => a而不是具體的Integer ,或者如果通過替換(Integral a) => Inc (a -> Integer)的實例來接受任意數量的參數,則類型推斷會變得更糟。 (Integral a) => Inc (a -> Integer) ,其中一個用於(Integral a, Inc i) => Inc (a -> i) 另一方面,您也可以為其他具體類型添加實例,例如IntDouble

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

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

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

然后第二個定義將影響第一個定義。 這意味着如果您調用“inc”,現在將使用第二個定義。

但是,您仍然可以通過部分應用程序完成所需的操作。 如果你使你的2個電話咖喱,它將具有相同的效果。 像這樣:

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

返回[2,3,4]

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

返回[3,4,5]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM