Haskell concat复制内链表推导



我在下面的练习中遇到了麻烦:

利用列表推导式,定义一个签名如下的函数:

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部分有关,但我不知道是什么。

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

列表推导式由结果表达式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不符合这些条件。这就是错误信息的内容:Haskell期望表达式的类型为Bool,但replicate返回的是一个列表。

要真正解决这个问题,您可以这样开始:

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

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

相关内容

  • 没有找到相关文章

最新更新