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]
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]
首先,简单的办法是只取了这个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)
接受任何数量的参数类型推断变得更糟糕。另一方面,您也可以为其他具体类型添加实例,例如Int
和Double
。
我想我的反问题是:你实际上试图解决什么问题?
不,这是不可能的。在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]
你可以通过类型类有多个参数的功能,有点欺骗,例如见Development.Shake.cmd。虽然我想添加一个免责声明 - 这不是初学者的东西,更多的是一个中间话题 – epsilonhalbe
作为另一个免责声明 - 即使在技术上可行的情况下,Haskell开发者也不是这样做的,因为它干扰了部分应用程序,我们一直使用*。这也是一种痛苦。 – luqui
另请参阅:[增量式特设参数抽象](https://byorgey.wordpress.com/2010/04/03/haskell-anti-pattern-incremental-ad-hoc-parameter-abstraction/)。 –