gpt4 book ai didi

haskell - 如何在 "parallel"中组合镜头

转载 作者:行者123 更新时间:2023-12-03 15:02:44 24 4
gpt4 key购买 nike

我是新手Control.Lens我正在尝试将 2 个镜头组合成“平行”(不是按顺序),就像我对 `Control.Arrow.&&& 所做的那样)。

如果我以 lens 为例文档:

`data Foo a = Foo { _baz :: Int, _bar :: Int, a }

我希望能够做类似的事情:
>> let foo = (bar &&& baz) .~ (1, 20) $ Foo undefined undefined "FOO"
>> foo ^. (bar &&& baz)
(1, 20)

我到处寻找,我找不到这样做的方法。那是因为:
  • (&&&) 以另一个名字存在,我错过了。
  • 没用的。我不应该需要它,因此没有人打扰实现它。
  • 用另一种方式做是微不足道的(使用 both<*> )

  • 更新
    &&&可以这样实现:
    (/|\) :: Lens' f a -> Lens' f b -> Lens' f (a, b)
    a /|\ b = lens getBoth setBoth where
    getBoth f = (f ^. a, f ^. b)
    setBoth f (v, w) = a .~ v $ f' where
    f' = b .~ w $ f

    barz :: Lens' Foo (Int, Int)
    barz = bar /|\ baz

    但是,它需要一个有点烦人的类型签名。

    最佳答案

    这个组合器可能无法实现。考虑:

    > (baz &&& baz) .~ (1,5)

    这应该怎么做?

    甚至更弱的组合器:
    (/|\) :: Lens' s a -> Lens' s a -> Traversal' s a
    a /|\ b = (a &&& b) . both

    会违反法律:

    比如我们看 baz /|\ baz .由于 Traversal也是 Setter ,它还必须满足 Setter laws .现在,采用第二个二传手法则:
    over (baz /|\ baz) (f . g) = over (baz /|\ baz) f . over (baz /|\ baz) g

    现在,我们得到:
    over (baz /|\ baz) (f . g) 
    = \(Foo _baz _bar) -> Foo (f . g . f . g $ _baz) _bar

    和:
    over (baz /|\ baz) f . over (baz /|\ baz) g
    = \(Foo _baz _bar) -> Foo (f . f . g . g $ _baz) _bar

    这两个显然是不同的。当两个镜头“重叠”时就会出现问题,而这并没有在类型中编码。

    关于haskell - 如何在 "parallel"中组合镜头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23321844/

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