我希望能够使用类似printf的功能创建一个字符串,从列表中提取变量并插入到模板字符串中。
即
let templateStr = "First comes %s, then comes %s, after which comes %s"
let vars = ["one","two", "three"]
并且某些函数返回:
function returns >>> First comes one, then comes two, after which comes three
即。在Python中我可以做类似的事情:
>>> templateStr = "First comes %s, then comes %s, after which comes %s"
>>> vars = ["one","two", "three"]
>>> outputStr = tempStr % tuple(vars)
>>> print outputStr
First comes one, then comes two, after which comes three
我的尝试
mergeList :: [a] -> [a] -> [a]
mergeList [] ys = ys
mergeList (x:xs) ys = x:mergeList ys xs
-- not actually needed * use: Prelude.concat
listConcat :: [[a]] -> [a]
listConcat [] = []
listConcat (x:xs) = x ++ listConcat xs
-- via @dfeuer list concat is not need because of Prelude.concat
printf' :: String -> [String] -> String
printf' s v = concat $ mergeList (splitOn "%s" s) v
尝试通过@Reid Barton
printf' :: String -> [String] -> String
printf' ('%':'s':rest) (v:vs) = v ++ printf' rest vs
printf' (c:rest) vs = c : printf' rest vs
printf' [] _ = []
两次尝试都给出了
>>> let templateStr = "First comes %s, then comes %s, after which comes %s"
>>> let vars = ["one","two", "three"]
>>> printf' templateStr vars
"First comes one, then comes two, after which comes three"
答案 0 :(得分:3)
另一种更直接的方法的概述:
printf' ('%':'s':rest) (v:vs) = ...
printf' (c:rest) vs = ...
... -- handle the remaining cases too
答案 1 :(得分:1)
好开始! mergeList
很干净。
mergeList :: [a] -> [a] -> [a]
mergeList [] ys = ys
mergeList (x:xs) ys = x:mergeList ys xs
listConcat :: [String] -> String
listConcat [] = []
listConcat (x:xs)
| null xs = x
| otherwise = x ++ listConcat xs
listConcat
你可以做得更好。特别是,您目前使用两个基本案例进行递归,但您只需要一个。此外,您可以将类型签名更改为listConcat :: [[a]] -> [a]
以使其更通用。一旦你清理了你的版本:标准库中就有这样的功能。你能找到吗?