Haskell concat在列表理解中复制

时间:2015-07-25 13:16:29

标签: haskell replication 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必须是原始列表的一个元素,所以使用elem x只有在它确实属于原始列表时才会被添加,并且复制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部分有关,但我不知道是什么。

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

1 个答案:

答案 0 :(得分:6)

列表理解包含结果表达式L和一个或多个以逗号分隔的右手形式R1R2,......排列如下:

[ 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不适合这些。这就是错误消息的内容:Haskell期望表达式具有类型Bool,但replicate返回一个列表。

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

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

现在notQuiteReproduce [3, 5, 1]会产生[[3,3,3],[5,5,5,5,5],[1]]。剩下的就是&#34;展平&#34;结果列表。这也可以通过列表理解来完成,但我不愿意只是解决问题。