Haskell函数的"默认值"?

Dar*_*rio 5 haskell

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

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

zr 1 = [0]
zr 5 = [0, 0, 0, 0, 0]
Run Code Online (Sandbox Code Playgroud)

等等.

我目前的实施方式是:

zr :: [Int] -> Int -> [Int]
zr x y
    | length x == y = x
    | otherwise = zr x++[y]
Run Code Online (Sandbox Code Playgroud)

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

zr [] 5
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

谢谢!

Ben*_*esh 13

我认为您正在寻找的是部分应用:

zr' :: Int -> [Int]
zr' = zr []
Run Code Online (Sandbox Code Playgroud)

如果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
Run Code Online (Sandbox Code Playgroud)

  • 另请注意,`zr = flip replicate 0` (4认同)

sol*_*sol 7

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

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

zr 0 = []
zr n = 0:(zr (n-1))
Run Code Online (Sandbox Code Playgroud)

这将导致0:0:[]for zr 2,其评估结果为[0,0].

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