【问题标题】:Haskell concat replicate inside list comprehensionHaskell concat 在列表理解中复制
【发布时间】:2015-07-25 21:31:46
【问题描述】:

我在以下练习中遇到了问题:

利用列表推导,定义一个具有以下签名的函数:

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

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

【问题讨论】:

  • 不,正如它在错误中所说,它与 replicate x x 有关,其中 Haskell 需要一个布尔值。
  • 为什么 Haskell 期望一个布尔值?我应该尝试在elem 验证中添加 == True 吗?
  • 因为这是唯一一个结果是 Bool 的地方(我认为),因此可能因为我没有 == 比较,当它到达复制谓词时,它会给出错误?
  • 复制不返回布尔值。这不是谓词。

标签: haskell replication list-comprehension


【解决方案1】:

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

[ L | R1, R2, ... ]

每个右边的形式必须是(1)一个生成器:

pattern <- expression

或 (2) let 绑定:

let pattern = expression

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

expression

在您的代码中,我们有三种这样的形式。 x &lt;- [1,2..10 ] 是一个生成器(案例 2),x `elem` xs 是一个过滤条件(案例 3),但 replicate x x 不符合这些条件。这就是错误消息的含义:Haskell 期望表达式的类型为 Boolreplicate 返回一个列表。


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

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

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

【讨论】:

  • 哦,所以如果我将理解开始时的 x 更改为复制,并从右侧表格中删除复制,它应该可以解决问题吗?
  • 是否可以在 notQuiteReproduce 函数中“展平”结果列表?因为我认为这应该在一个函数中完成。
  • 好的,我会解决的,非常感谢您的帮助。
猜你喜欢
  • 2018-06-07
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多