gpt4 book ai didi

haskell - 为什么在 Haskell 的镜头库中同时具有 itraverse 和 itraversed 函数?

转载 作者:行者123 更新时间:2023-12-01 23:28:40 26 4
gpt4 key购买 nike

Haskell 库 lens 包含一个类型类 TraversableWithIndex,它定义了函数 itraverseitraversed:

class
(FunctorWithIndex i t, FoldableWithIndex i t, Traversable t)
=> TraversableWithIndex i t | t -> i where
itraverse :: Applicative f => (i -> a -> f b) -> t a -> f (t b)
itraversed :: IndexedTraversal i (t a) (t b) a b

IndexedTraversal 展开如下:

type IndexedTraversal i s t a b =
forall p f. (Indexable i p, Applicative f) => p a (f b) -> s -> f t

itraverseitraversed 看起来很相似。 为什么两者都需要?


通过使用 itraverseitraversed,看来 itraversed 是两者中唯一可以与 %@~ 一起使用的一个 AnIndexedSetter

为了完整性,下面是%@~AnIndexedSetterIndexed的类型:

(%@~) :: AnIndexedSetter i s t a b -> (i -> a -> b) -> s -> t 

type AnIndexedSetter i s t a b =
Indexed i a (Identity b) -> s -> Identity t

newtype Indexed i a b = Indexed { runIndexed :: i -> a -> b }

为什么 %@~ 需要 AnIndexedSetter?为什么无论如何都必须使用 Indexed

使用 Indexed 似乎会使组合变得更加困难,因为它不是一个普通函数。 我在这里错过了什么?

最佳答案

索引光学器件不像普通光学器件那么简单。常规遍历很简单:

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t

这正是遍历的类型,s = c at = c b,其中c是一个 Traversable

您可以想象 IndexedTraversal i(i -> a -> f b) 类似;但事实并非如此!

type IndexedTraversal i s t a b =
forall p f. (Indexable i p, Applicative f) => p a (f b) -> s -> f t

Indexable i p 约束由(->)Indexed 满足,所以:

itraverse  :: Applicative f => (i -> a -> f b) -> s -> f t
itraversed :: Applicative f => (a -> f b) -> s -> f t -- (->)
itraversed :: Applicativef => Indexed i a b -> s -> f t

在哪里

newtype Indexed i a b = Indexed { runIndexed :: i -> a -> b } 

为什么两者都需要? itraverse 更容易实现。通常它已经存在(例如 containers 中的 traverseWithKey)。


操作需要具体的光学实例(例如,set 需要 ASetter)。简而言之:编译器更容易理解出东西,因为我们不使用 Rank2Types

Indexed 即需要单独的 newtype 以便我们可以讨论关于 a -> bi -> a -> b 作为 Indexable 的实例;让我们将索引光学器件降级为常规光学器件:

Prelude Control.Lens> over itraversed (+1) [1,2,3]
[2,3,4]

并且有 p a (f b) -> q s (f t)(其中 p 可以是 (->)Indexable )让我们组成索引和常规光学器件:

Prelude Control.Lens> over (itraversed . traversed)  (+1) [[1,2],[3]]
[[2,3],[4]]

Prelude Control.Lens> iover (itraversed . traversed) (,) [[1,2],[3]]
[[(0,1),(1,2)],[(0,3)]]

关于haskell - 为什么在 Haskell 的镜头库中同时具有 itraverse 和 itraversed 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43663596/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com