如何在Haskell中复制和合并String?

时间:2017-11-26 19:08:10

标签: haskell

我试图实现一个输入字符串列表的函数,即

["test1","test2"]

它将返回列表的复制,将其转换为

["test1test1","test2test2"]

我尝试使用replicate实现它,但是将其转换为

[["test1","test2"],["test1","test2"]]. 

3 个答案:

答案 0 :(得分:5)

由于map (\x -> x++x) 重复单个字符串,所需的是

users{
  user1:{
    email: 'user1@email.com',
    points: '5'
  },
  user2:{
    email: 'user2@email.com',
    points: '3'
  },
  ....
}

答案 1 :(得分:4)

如果您想使用replicate,则需要concat添加每个内部列表中的所有字符串:

-- Create n copies of the string, then concatenate them
dupStr :: Int -> String -> String
dupStr n = concat . replicate n

-- Same thing on each element of a list of strings
dupStrs :: Int -> [String] -> [String]
dupStrs n = map $ dupStr n

-- Your function specifically
dup2 :: [String] -> [String]
dup2 = dupStrs 2

dupStr 3 "a" == "aaa"
dupStrs 2 ["t1", "t2"] == ["t1t1", "t2t2"]
dup2 ["test1", "test2"] == ["test1test1", "test2test2"]

这适用于任何重复次数。

答案 2 :(得分:1)

你可以直观地做到这一点,而不用口头上的想法:

g :: [[t]] -> [[t]]
g xs = [ [c | y <- [x,x], c <- y]  | x <- xs ]

现在我们已经有了它,我们可以认识到它等同于

     = [  concat   [x,x]           | x <- xs ]
     = [  concat  (replicate 2  x) | x <- xs ]
     = [ (concat . replicate 2) x  | x <- xs ]
     = map (concat . replicate 2)         xs

现在很有口头表达。无论什么样的风格对你来说都比较容易。

(f . g) x = f (g x)函数组合,将右侧函数的输出作为输入汇总到左侧的函数中。有些人喜欢无点风格,

g :: [[t]] -> [[t]]
g = map (concat . replicate 2)

(&#34; point&#34;在xs的定义中引用g xs = ...;没有参数的定义被称为无点样式。

嗯,实际上,concat [x,x]只是x ++ x = (++) x x = join (++) x,所以我们甚至可以写

  = map (join (++))

但这种风格需要习惯。如果我们想要连接三个甚至更多的字符串副本也是没有用的,这很容易用上面的样式安排,甚至定义一个新的函数,

g :: Int -> [[t]] -> [[t]]
g n = map (concat . replicate n)