我在以下练习中遇到了麻烦:
利用列表理解,定义具有以下签名的函数:
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
部分有关,但我不知道是什么。
注意:这是初学者练习,因此应该以简单的方式解决。
答案 0 :(得分:6)
列表理解包含结果表达式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]]
。剩下的就是&#34;展平&#34;结果列表。这也可以通过列表理解来完成,但我不愿意只是解决问题。