繁体   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