gpt4 book ai didi

haskell - 使用镜头两次

转载 作者:行者123 更新时间:2023-12-03 15:05:16 26 4
gpt4 key购买 nike

我正在努力使用 lens特定问题的库。我试图通过

  • 更新的数据结构
  • 聚焦于更新结构的一部分

  • 到另一个函数, g .我通过了镜头和数据结构,因为 g需要数据结构中的一些共享信息以及一条信息。 (如果有帮助,数据结构包含有关联合概率分布的信息,但 g 仅适用于任一边缘,需要知道我正在查看哪个边缘。两个边缘之间的唯一区别是它们与其余边缘的平均值它们的定义在数据结构中共享)。

    我的第一次尝试看起来像这样
    f :: Functor f => Params -> ((Double -> f Double) -> Params -> f Params) -> a
    f p l = g (l %~ upd $ p) l
    where upd = ...

    g p x = go p p^.x

    但在编译过程中失败,因为 f被推断为 Identity对于更新和 Const Double为 setter/getter 。

    完成我想做的事情的最佳方法是什么?我可以想象能够执行以下操作之一:
  • 复制镜头,以便在每种情况下类型推断都不同
  • 我没有传递更新的结构和镜头,而是传递了原始结构和一个返回修改值的镜头(如果我只想更新镜头所看到的结构部分)。
  • 为我的函数/数据结构做出更好的设计选择
  • 完全不同的东西

  • 谢谢你的帮助!

    最佳答案

    András Kovács answer显示如何使用 RankNTypes 实现此目的.如果您想避免 RankNTypes , 那么你可以使用 ALenscloneLens :

    f :: a -> ALens' a Int -> (Int, a)
    f a l = (newvalue, a & cloneLens l .~ newvalue)
    where oldvalue = a^.cloneLens l
    newvalue = if oldvalue == 0 then 0 else oldvalue - 1

    Control.Lens.Loupe提供在 ALens 上工作的运算符和函数而不是 Lens .

    请注意,在许多情况下,您还应该能够使用 <<%~ ,就像 %~但也返回旧值,或 <%~ ,它返回新值:
    f :: a -> LensLike' ((,) Int) a Int -> (Int, a)
    f a l = a & l <%~ g
    where g oldvalue = if oldvalue == 0 then 0 else oldvalue - 1

    这样做的好处是它也可以与 Isos 一起使用。或者有时也与 Traversals (当目标类型是 Monoid 时)。

    关于haskell - 使用镜头两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23424203/

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