【问题标题】:No instance for Foldable arising from length inside lambda没有由 lambda 内的长度引起的可折叠实例
【发布时间】:2020-08-23 01:51:32
【问题描述】:

这里的第一个问题,完全是haskell的菜鸟,所以请善待我:)

我在玩thishaskell 练习的第 6 题

最后用这段代码找到了解决方案(或者我希望的类似的东西)

combinations gr lis = filter clean $ sequence $ replicate gr lis
where
    clean string
        | total > gr = False
        | otherwise = True
        where total = sum [ rpt c string | c <- string]
    rpt chr list = length $ filter (== chr) list

我喜欢强调的部分是函数'rpt',它计算一个字符在字符串中重复的次数,例如: "aaba" -> [3313](3 来自字母 a,重复 3 次) “aaccva”-> [332213]

后来我尝试使用 lambda 和 map 来制作函数,结果如下:

rpt chr list = map (\chr -> length $ filter (== chr)) list

起初 ghci 告诉我使用 FlexibleContext 来允许这样做,但如果我这样做了,它就会产生:

<interactive>:7:1:
No instance for (Foldable ((->) [Char]))
  arising from a use of ‘rpt’
In the expression: rpt 'a' string
In an equation for ‘it’: it = rpt 'a' string

在这里我被卡住了,我无法理解发生了什么......修复这个功能需要什么?

【问题讨论】:

  • 这在结构上对你说的初学者来说非常好,你有这个诀窍
  • 作为在这些情况下的一般建议,当您收到令人困惑的错误消息时,请开始添加类型注释,说明您认为类型应该是什么。这将显着改善错误消息。事实上,为所有顶级函数提供类型注释以尽快发现此类错误通常是一种很好的做法。
  • 这对初学者有好处。几点注意事项:1)考虑clean string = total &lt;= gr where ...,因为使用警卫或if-then-else返回真/假看起来比它需要的更复杂2)您的组合算法看起来正确但不是最佳的:您生成了许多候选者,并且您需要稍后将它们过滤掉。考虑一下:您可以通过跳过x(并从xs 中获取所有k 个元素)或选择x(然后仅从xs 中获取k-1 个元素)来从x:xs 中选择k 个元素。

标签: haskell lambda foldable


【解决方案1】:

您可能打算过滤 list,因此为了使您的代码正常工作,您还需要添加 list 作为 filter 的参数:

rpt chr list = map (\chr -> length $ filter (== chr) list) list

对于初学者,我建议忽略 GHCi 的FlexibleContexts 的建议。它通常最终会产生类似于您所拥有的错误消息(或其他令人困惑的消息,例如 No instance for (Num (Int -&gt; Bool)))。

【讨论】:

  • 建议:他真正想要的修复是在映射函数的末尾包含list(如map (\chr -&gt; length $ filter (== chr) list) list)。您的代码会生成一个函数列表;我的会产生一个数字列表。
  • @DanielWagner 我认为你是对的。我会相应地修改解决方案。
  • 哇,这么简单的解决方案...谢谢@Alec,你帮了我很多!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 2021-04-30
  • 2016-03-24
  • 2023-03-14
  • 2022-01-12
相关资源
最近更新 更多