【问题标题】:What are some Foldable instances that are _not_ "general Foldable structures" in the sense of Data.Foldable?在 Data.Foldable 的意义上,有哪些可折叠的实例_不是_“一般可折叠结构”?
【发布时间】:2023-03-14 14:13:01
【问题描述】:

documentation for Foldable 列出了“通用可折叠结构”所需的几个属性:

  • 对于foldr

    对于一般的可折叠结构,这在语义上应该是相同的,

    foldr f z = foldr f z . toList
    
  • 对于foldl

    对于一般的可折叠结构,这在语义上应该是相同的,

    foldl f z = foldl f z . toList
    
  • 对于foldl'(在我看来像是一个错字):

    对于一般的可折叠结构,这在语义上应该是相同的,

    foldl f z = foldl' f z . toList
    

Foldable 的哪些实例不需要或不能保持这些属性?

【问题讨论】:

  • 我认为应该阅读这些属性确实需要为所有表现良好的实例保留。不过不太确定。
  • 我认为这些属性都是有规律的。
  • foldl 法律仅适用于有限结构。对于无限的 snoc-list,foldl 应该比这更好地定义。
  • 我认为“对于一般的可折叠结构,这应该在语义上相同”只是“对于任何可折叠结构,这应该在语义上相同”,甚至“这应该在语义上相同”的迂回说法.
  • 感谢 cmets!我想我会尽快提出一个不那么含糊的措辞。

标签: haskell foldable


【解决方案1】:

据我了解,如果实例定义了这些可选函数,则这些是实例必须遵守的规则。默认情况下,Foldable 实例只需定义foldMapfoldr。根据这两个定义之一,类型类的所有其他函数都会自动遵循。

然而,通常,类型类让您可以选择定义更多类型类的行为。如果toList 的默认自动定义效率低下,并且您希望提供更有效的实现,这将很有用。这对于Monoid 类型类可能更容易理解,它将mconcat 定义为可选函数,“以便可以为特定类型提供优化版本”。

OP 中引用的法则是如果您选择自己定义部分或全部这些函数,实例必须遵守的法则。作为违反规则的(无意义的)类型的示例,请考虑以下Invalid 类型:

import Data.Foldable

data Invalid a = Invalid a deriving (Show, Eq)

instance Foldable Invalid where
  foldMap f (Invalid x) = f x
  foldr _ x _ = x -- Unlawful!!
  toList (Invalid x) = [x]

虽然它只需将foldMap 定义为Foldable 实例,但它还定义了foldrtoList。虽然toList 定义很好,但foldr 定义违反了规则:

*Q53460772 Data.Monoid Data.Foldable> toList $ Invalid 42
[42]
*Q53460772 Data.Monoid Data.Foldable> foldMap Sum $ Invalid 42
Sum {getSum = 42}
*Q53460772 Data.Monoid Data.Foldable> f = \x acc -> x + acc
*Q53460772 Data.Monoid Data.Foldable> z = 0
*Q53460772 Data.Monoid Data.Foldable> (foldr f z . toList) $ Invalid 42
42
*Q53460772 Data.Monoid Data.Foldable> foldr f z $ Invalid 42
0

toListfoldMap 函数的行为与您期望的一样,但请注意 foldr f z 不会产生与 foldr f z . toList 相同的输出。

虽然Invalid 是一个无意义的示例,但它表明您可以编写可编译的代码,并且看起来它提供了Foldable 的实例。然而,与每个函数相关的法律和规则清楚地表明这不是一个有效的实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    相关资源
    最近更新 更多