Haskell函数的“默认值”?

时间:2014-05-06 08:18:42

标签: haskell

是否可以预先定义函数的输入值,以便用户不必每次都定义它们?

例如,假设我有一个函数“zr”,它返回一个大小为n的列表零,这样:

zr 1 = [0]
zr 5 = [0, 0, 0, 0, 0]

等等。

我目前的实施方式是:

zr :: [Int] -> Int -> [Int]
zr x y
    | length x == y = x
    | otherwise = zr x++[y]

但这并不是特别优雅,因为每次调用zr我都需要包含一个空列表作为参数:

zr [] 5

有什么想法吗?

谢谢!

3 个答案:

答案 0 :(得分:13)

我认为您正在寻找的是部分申请

zr' :: Int -> [Int]
zr' = zr []

如果zr是一个采用列表和整数的函数,那么zr []是一个仅取整数n并返回zr [] n的函数。

在你的情况下,zr显然是一个“临时”功能(你不希望任何人意外地调用zr [1] 4),所以你不妨在本地定义它:

zr :: Int -> [Int]
zr = zr' []
  where
     zr' :: [Int] -> Int -> [Int]
     zr' x y
         | length x == y = x
         | otherwise = zr' x++[0] y

答案 1 :(得分:7)

不是Haskell专业人士,但除了定义速记函数(zz n = zr [] n)之外,我不知道其他方法。

在具体情况下,还有另一种解决方案:
您不应该通过参数循环输出,使用返回值作为递归方式:

zr 0 = []
zr n = 0:(zr (n-1))

这将导致0:0:[]的{​​{1}},其评估结果为zr 2

你的版本非常无效,因为它计算每一步列表的长度,无条件地保持结束值(你可以递减它并将0作为终点)并进行比较。

答案 2 :(得分:0)

根据您的需要,有三种选择:

  1. 传递带有函数参数的记录类型,并定义" defaultParameters"使用这些参数的默认值(see example in System.Process module
  2. 如果您只想允许一个可选的函数参数,您可以考虑使用Maybe数据类型,如果默认值足够则传递Nothing
  3. 如果您希望拥有一个取决于范围的本地默认值,请使用GHC扩展ImplicitParams。它将允许您定义给定代码段的默认值,然后由本节范围内的所有内容使用。