Haskell:使用Map应用具有多个参数的函数

时间:2014-10-29 13:29:07

标签: haskell

我想要这样的东西:

helpPadNumbers [“123”,“45”,“1”] 4

结果应为:[“#123”,“## 45”,“### 1”] 而不是'#'它应该是''(空格) 在我的方法之后,所有元素具有相同的长度。

helpPadNumbers :: [String] -> Int -> [String]
helpPadNumbers x 0 = x
helpPadNumbers x a = map ((test1 x a) a)

test1 :: String -> Int -> String
test1 x a = (spaces1 ((a-length x))) ++ x

spaces1 :: Int -> String
spaces1 0 = ""
spaces1 n = " " ++ spaces1 (n-1)

我的问题是:如何使用map函数分别获取列表中的每个元素?

错误:“可能的原因:'map'适用于太少的参数”

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:7)

你走在正确的轨道上 - map确实是你想要的。 因此,让我们从一个工作版本开始快速回答:

helpPadNumbers :: [String] -> Int -> [String]
helpPadNumbers x 0 = x
helpPadNumbers x a = map (\ xs -> test1 xs a) x

看看那里的地图 - 你的问题基本上是顺序和parens。

让它看起来更漂亮

当然,这不是真正的Haskell风格,所以让我们重新排序你的论点(并删除一些parens):

helpPadNumbers :: Int -> [String] -> [String]
helpPadNumbers 0 xs = xs
helpPadNumbers a xs = map (test1 a) xs

test1 :: Int -> String -> String
test1 a x = spaces1 (a - length x) ++ x

spaces1 :: Int -> String
spaces1 0 = ""
spaces1 n = " " ++ spaces1 (n-1)

你可以看到这个版本使用了部分应用程序,我们不需要那里的lambda表达式。它看起来也更好IMO

(++)不是你的朋友

看看space1 - 您所做的只是前置一个空格字符,但使用列表和共同点 - 并非真正需要:

spaces1 :: Int -> String
spaces1 0 = ""
spaces1 n = ' ' : spaces1 (n-1)

正如您所看到的那样,使用(:)来预先添加一个更高效的空格字符' '

说到space1:已经有了这样的功能:replicate

spaces1 :: Int -> String
spaces1 n = replicate n ' ' 

进一步简化

replicate相当宽容(负数或零没有问题) - 我们并不需要上面a = 0的情况。所以我们可以进一步简化:

helpPadNumbers :: Int -> [String] -> [String]
helpPadNumbers n xs = map (test1 n) xs

test1 :: Int -> String -> String
test1 n x = spaces1 (n - length x) ++ x

spaces1 :: Int -> String
spaces1 n = replicate n ' ' 

我认为我们可以将辅助函数放入where子句:

helpPadNumbers :: Int -> [String] -> [String]
helpPadNumbers n = map spaces
  where spaces xs = replicate (n - length xs) ' ' ++ xs
例:

这是一个使用上一个版本的示例:

λ> helpPadNumbers 4 ["12345", "1234","123","12","1",""]
["12345","1234"," 123","  12","   1","    "]