为什么在Haskell的镜头库中同时具有itraverse和itraversed功能?

时间:2017-04-27 16:45:37

标签: haskell indexing traversal lens

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似乎非常相似。 为什么两者都需要?

通过使用itraverseitraverseditraversed似乎是%@~中唯一可以与%@~一起用作AnIndexedSetterAnIndexedSetter }。

以下是完整性Indexed(%@~) :: 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?为什么必须使用compsMap.get(key)

使用const compsMap = new Map([ ['id', "<TableHeaderColumn dataField={'id'} width='50' isKey autoValue={true} dataAlign='left' dataSort >{'id'}</TableHeaderColumn>"], ['firstName', "<TableHeaderColumn dataField={'firstName'} dataSort headerAlign='left' editable={JSON.parse('{type: 'textarea' }')}>{'First Name'}</TableHeaderColumn>"], ['lastName', "<TableHeaderColumn dataField={'lastName'} dataSort headerAlign='left' editable={JSON.parse('{'type': 'textarea' }')}>{'Last Name'}</TableHeaderColumn>"], ['mobile', "<TableHeaderColumn dataField={'mobile'} dataSort headerAlign='left' editable={JSON.parse('{'type': 'textarea' }')}>{'Mobile'}</TableHeaderColumn>"], ['username', "<TableHeaderColumn dataField={'username'} dataSort headerAlign='left' editable={JSON.parse('{'type': 'textarea' }')}>{'Username'}</TableHeaderColumn>"] ]); console.log('compsMap[id] = ', compsMap.get('id'));似乎会使合成变得更加困难,因为它不是正常的功能。 我在这里缺少什么?

1 个答案:

答案 0 :(得分:4)

索引光学并不像普通光学一样简单。常规Traversal很简单:

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

这正是具有traverses = c a的{​​{1}}的类型,其中t = c bc

您可以想象TraversableIndexedTraversal 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中的traverseWithKey)。

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

Rank2Types,即需要单独的Indexed,以便我们进行交流 约newtypea -> b作为i -> 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]]