Haskell concat replicate inside 列表理解

Haskell concat replicate inside list comprehension

我在进行以下练习时遇到了问题:

利用列表理解,定义具有以下签名的函数:

reproduce :: [Int] -> [Int]

此函数将列表中的每个数字都替换为其自身的 x 个副本。

例如:

input: reproduce[3,5,1]
output: [3,3,3,5,5,5,5,5,1]

我做了以下事情:

reproduce :: [Int] -> [Int]
reproduce xs = [ x | x <- [1,2..10 ] , x `elem` xs , replicate x x ]

我的想法是让 x 属于一个小区间,x 必须是原始列表的一个元素,所以使用 elemx 只会在它确实属于原始列表时添加,并且复制 x , x 次,以获得自己的 x 个副本。

当我尝试加载此函数时,出现以下错误消息:

Couldn't match expected type `Bool' with actual type `[Int]'
In the return type of a call of `replicate'
In the expression: replicate x x
In a stmt of a list comprehension: replicate x x

我不知道如何解决这个错误,我假设它与 elem 部分有关,但我不知道是什么。

注意:这是一个初学者练习,因此应该以简单的方式解决。

列表理解由结果表达式 L 和一个或多个逗号分隔的右手形式组成 R1, R2, ... 排列如下:

[ L | R1, R2, ... ]

每个右侧形式必须是 (1) 生成器:

pattern <- expression

或 (2) let 绑定:

let pattern = expression

或(3)过滤条件(返回Bool的表达式):

expression

在您的代码中,我们有三种这样的形式。 x <- [1,2..10 ] 是生成器(情况 2),x `elem` xs 是过滤条件(情况 3),但 replicate x x 适合其中的 none。这就是错误消息的内容:Haskell 期望表达式的类型为 Boolreplicate returns 是一个列表。


要真正解决问题,您可以先这样做:

notQuiteReproduce xs = [ replicate x x | x <- xs ]

现在 notQuiteReproduce [3, 5, 1] 产生 [[3,3,3],[5,5,5,5,5],[1]]。剩下的就是 "flatten" 结果列表。这也可以通过列表理解来完成,但我不愿意直接给出解决方案。