Haskell库lens包含一个类型类TraversableWithIndex,它定义了函数itraverse和itraversed:
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
itraverse
和itraversed
似乎非常相似。 为什么两者都需要?
通过使用itraverse
和itraversed
,itraversed
似乎是%@~
中唯一可以与%@~
一起用作AnIndexedSetter
的AnIndexedSetter
}。
以下是完整性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'));
似乎会使合成变得更加困难,因为它不是正常的功能。 我在这里缺少什么?
答案 0 :(得分:4)
索引光学并不像普通光学一样简单。常规Traversal
很简单:
type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t
这正是具有traverse
和s = c a
的{{1}}的类型,其中t = 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
中的traverseWithKey
)。
操作需要光学器件的具体实例化
(例如containers
需要set
)。简而言之:编译器更容易理解
因为我们不使用ASetter
。
Rank2Types
,即需要单独的Indexed
,以便我们进行交流
约newtype
和a -> 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]]