【问题标题】:Haskell :How to define an instance of the constructor class Foldable for the constructorHaskell:如何为构造函数定义构造函数类Foldable的实例
【发布时间】:2021-04-28 00:15:41
【问题描述】:

我刚刚开始使用 Haskell,在阅读了 Foldable 文档后,我正在尝试为构造函数 ListBag 定义构造函数类 Foldable 的实例,其中: newtype ListBag a = LB [(a,Int)] deriving (Show,Eq)

为了这个目标,我有一个二进制函数 f,它适用于我的多重集的第一个元素。 这就是我尝试过的:

instance Foldable ListBag where
  foldr f z (LB[]) = 0 
  foldr f z (LB [x]) = f i z where (i,_) = x
  foldr f z (LB [x : xs]) = f i foldr f z (LB[xs]) where (i,_) = x

这是不正确的,但我能做到的最好...

知道如何纠正吗?

(是的,应该应用 f 函数忽略多重性。)

【问题讨论】:

  • 一个值LB [(x,2), (y,3)] 是否意味着代表两个x 和三个y?是这样,你需要产生f x (f x (f y (f y (f y z))))。您不能将整数传递给f,也不能从foldr 返回整数,就像您现在正在尝试做的那样。
  • @chi 他们没有将整数传递给f,即使在纠正了他们的模式匹配之后。
  • @chi 感谢您抽出宝贵时间,是的,这就是 LB 的创建方式,但目前我想将 f 应用于第一个元素 忽略多重性
  • 我明白了。给定list :: [(a,Int)],我们有map fst list :: [a],因此您可以将foldr 应用于标准列表。如果您想改正您的方法,请不要将LB [x]LB [x:xs] 用于您的模式。要匹配非空列表,您需要改用LB (x:xs),或LB ((x,_):xs) 仅获取第一个组件。
  • @DanielWagner 啊,对。我被 i 这个名字弄糊涂了,我认为它是 Int 组件。

标签: haskell multiset foldable


【解决方案1】:

模式[x] 匹配一个包含一个元素的列表,就像您希望的那样。但是模式[x : xs] also 匹配一个带有一个元素的列表——它本身必须是一个列表,并且非空。你想要(x : xs)。 (同样地,在该行中,您需要LB xs,而不是LB [xs],因为后者试图在列表尾部包裹一层额外的列表。)

另外,我猜你会更高兴看到一个实例,当它看到(i,v) 时,会假装有iv 副本,而不是总是只合并一次i

【讨论】:

  • 谢谢丹尼尔,这真的很有帮助。我根据您和@chi 所说的内容编辑了代码。你现在觉得合适吗?
  • @mohammadfarhady 是的,看起来不错。但是,请不要在未来进行那种编辑(我已经回滚了)。 StackOverflow 的目标是作为问题及其答案的存档集合——因此在回答问题后大幅改变问题的内容并不是一种好的形式。如果您还有其他问题,可以打开一个新问题,描述您面临的下一个障碍。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-04
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 2015-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多