不是函子(或不可遍历)的可折叠示例?

发布于 2024-12-19 06:16:04 字数 544 浏览 5 评论 0原文

可折叠 实例可能是某种容器,因此也可能是一个函子。事实上,

Foldable类型也是一个容器(尽管该类在技术上不需要Functor,有趣的Foldable都是Functors)。

那么是否有一个 Foldable 的例子,它本质上不是一个 FunctorTraversable ? (也许 Haskell wiki 页面错过了:-))

A Foldable instance is likely to be some sort of container, and so is likely to be a Functor as well. Indeed, this says

A Foldable type is also a container (although the class does not technically require Functor, interesting Foldables are all Functors).

So is there an example of a Foldable which is not naturally a Functor or a Traversable? (which perhaps the Haskell wiki page missed :-) )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

柏拉图鍀咏恒 2024-12-26 06:16:04

这是一个完全参数化的示例:

data Weird a = Weird a (a -> a)

instance Foldable Weird where
  foldMap f (Weird a b) = f $ b a

Weird 不是 Functor,因为 a 出现在负数位置。

Here's a fully parametric example:

data Weird a = Weird a (a -> a)

instance Foldable Weird where
  foldMap f (Weird a b) = f $ b a

Weird is not a Functor because a occurs in a negative position.

哭泣的笑容 2024-12-26 06:16:04

这是一个简单的示例:Data.Set.Set。 亲自看看。

如果您检查为 Set 定义的专用 foldmap 函数的类型,其原因应该很明显:

foldr :: (a -> b -> b) -> b -> Set a -> b

map :: (Ord a, Ord b) => (a -> b) -> Set a -> Set b

因为数据结构依赖于二叉搜索树内部,元素需要 Ord 约束。 Functor 实例必须允许任何元素类型,所以这是不可行的,唉。

另一方面,折叠总是破坏树来产生汇总值,因此不需要对折叠的中间结果进行排序。即使折叠实际上正在构建一个新的Set,满足Ord约束的责任在于传递给折叠的累积函数,而不是折叠本身。

这同样可能适用于任何不完全参数化的容器类型。考虑到 Data.Set 的实用性,我认为这使得您引用的有关“有趣的”Foldable 的评论似乎有点可疑!

Here's an easy example: Data.Set.Set. See for yourself.

The reason for this should be apparent if you examine the types of the specialized fold and map functions defined for Set:

foldr :: (a -> b -> b) -> b -> Set a -> b

map :: (Ord a, Ord b) => (a -> b) -> Set a -> Set b

Because the data structure relies on a binary search tree internally, an Ord constraint is needed for elements. Functor instances must allow any element type, so that's not viable, alas.

Folding, on the other hand, always destroys the tree to produce the summary value, so there's no need to sort the intermediate results of the fold. Even if the fold is actually building a new Set, the responsibility for satisfying the Ord constraint lies on the accumulation function passed to the fold, not the fold itself.

The same will probably apply to any container type that's not fully parametric. And given the utility of Data.Set, this makes the remark you quoted about "interesting" Foldables seem a bit suspect, I think!

好多鱼好多余 2024-12-26 06:16:04

阅读美丽的折叠
将其包装成 Functor

data Store f a b = Store (f a) (a -> b)

我意识到任何 Foldable 都可以通过使用简单的智能构造函数

store :: f a -> Store f a a
store x = Store x id

:(这只是 存储 comonad 数据类型。)

现在我们可以 。

instance Functor (Store f a) where
    fmap f (Store x g)   = Store x (f . g)

instance (F.Foldable f) => F.Foldable (Store f a) where
    foldr f z (Store x g)    = F.foldr (f . g) z x

这样,我们就可以将 Data.Set.Set 和 Sjoerd Visscher 的 Weird 都设为函子 (但是,由于该结构不会记住其值,因此如果我们在 fmap 中使用的函数很复杂,则重复折叠它可能会非常低效。)


更新:这也提供了一个函子结构的示例,可折叠但不可遍历。为了使 Store 可遍历,我们需要使 (->) r 可遍历。因此,我们需要实现

sequenceA :: Applicative f => (r -> (f a)) -> f (r -> a)

Let's take Either b for f。那么我们需要实现

sequenceA' :: (r -> Either b a) -> Either b (r -> a)

显然,没有这样的功能(你可以用 Djinn 来验证) 。所以我们都无法实现sequenceA

Reading Beautiful folding
I realized that any Foldable can be made a Functor by wrapping it into

data Store f a b = Store (f a) (a -> b)

with a simple smart contructor:

store :: f a -> Store f a a
store x = Store x id

(This is just a variant of the Store comonad data type.)

Now we can define

instance Functor (Store f a) where
    fmap f (Store x g)   = Store x (f . g)

instance (F.Foldable f) => F.Foldable (Store f a) where
    foldr f z (Store x g)    = F.foldr (f . g) z x

This way, we can make both Data.Set.Set and Sjoerd Visscher's Weird a functor. (However, since the structure doesn't memoize its values, repeatedly folding over it could be very inefficient, if the function that we used in fmap is complex.)


Update: This also provides an example of a structure that is a functor, foldable but not traversable. To make Store traversable, we would need to make (->) r traversable. So we'd need to implement

sequenceA :: Applicative f => (r -> (f a)) -> f (r -> a)

Let's take Either b for f. Then we'd need to implement

sequenceA' :: (r -> Either b a) -> Either b (r -> a)

Clearly, there is no such function (you can verify with Djinn). So we can neither realize sequenceA.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文