gpt4 book ai didi

haskell - 有人可以解释有关“镜头”库的图吗?

转载 作者:行者123 更新时间:2023-12-03 13:23:20 29 4
gpt4 key购买 nike

如果您浏览有关镜头的Lens条目,Lens Github的存储库,甚至是有关Lens的Google,您会发现很多局部参考,例如入门教程/视频,示例,概述等。由于我已经了解大多数基本知识,因此我正在寻找更完整的参考资料,以帮助我获得有关高级功能的更多知识。换句话说,我仍然不知道this是什么意思,并且找不到足够完整的资源来整体解释该图形。有想法吗?

最佳答案

黑线鳕是最好的深度资源。它们包含了所有内容,但是起初它们可能有点难以导航。只需浏览不同的模块并在什么地方做一些心理记录,您很快就会发现自己的出路。链接到的图也是一个很好的模块图。

但是,由于您说您不了解该图形,因此我假设您不需要高级或完整的参考。该图实际上是lens包的各个部分的非常基本的高级概述。如果您不理解该图,则可能应该等一下高级内容。

在阅读本文时,请记住,尽管lens包最初是由透镜组成的包,但是现在包中有很多光学器件,它们遵循不同的定律并且用于不同的事物。 “光学”是用于戳戳数据结构的类似镜头的事物的通用名称。

无论如何,这就是我阅读图表的方式。

箱子的安排

现在,仅需查看光学元件名称的书写框顶部。

  • 顶层FoldSetterlens的基本原理。可以想象,Setter是设置某个字段值的光学元件。我将在这里省略很多示例,因为您说您了解大多数基础知识,但实际上,当您这样做时,
    λ> ellen & age .~ 35
    Person { _name = "Ellen", _age = 35 }

    那么您已经使用age作为Setter
  • Getter是一种特殊的Fold,可让您从数据结构中获取值。 (Fold本身仅允许您以某种方式将值组合为新值,而不能按原样获取它们。)Getter是一种特殊的Fold,在图形中由从Getter指向Fold的箭头标记。
  • 如果您将FoldSetter组合在一起(即,您组合了循环一堆值的方法和设置单个值的方法),则会得到TraversalTraversal是针对多个元素的光学元件,可让您设置或修改所有元素。
  • 在图表的更下方,如果将GetterTraversal组合在一起,则会得到Lens。这对您应该很熟悉,因为通常将镜头称为“ setter和getter 的组合”,并且您可以将Traversal视为更强大的Setter
  • 我不会假装我对ReviewPrismIsoEquality之间的关系了解很多。我的理解方式
  • Review是函数b -> t的基本包装,其中b应该是t结构内的一个字段。因此,Review使用单个字段值,然后围绕它构造一个整体结构。这可能看起来很愚蠢,但实际上是Getter的反向操作,对于构建棱柱很有用。
  • Prism允许您在分支类型中获取和设置值。元组是Either,是Lens。您不能仅凭镜头获得Either内部的值,因为如果它碰到Left分支,它将爆炸。
  • IsoLensPrism的非常强大的组合,可让您通过光学元件自由地“双向浏览”。虽然Lens使您可以从高层看数据结构的精确部分,但是Iso也使您从数据结构的查明部分的高层进行观察。
  • 一个Equality是...我不知道,抱歉。

  • 插曲:类型签名

    一开始,像 Lens s t a b这样的类型签名可能会令人恐惧,因此,我将尝试快速介绍它的含义。如果查看 Getter,您会看到其类型签名为
    Getter s a

    如果我们从概念上考虑什么是 setter/getter ,这似乎很熟悉。什么是 setter/getter ?它是从数据结构 s到该结构内部的单个值 a的函数。例如,函数 Person -> Age是从 Person对象获取年龄的 setter/getter 。相应的 Getter仅具有签名
    Getter Person Age

    真的就是这么简单。 Getter s a是一种光学器件,可以从 a内部获取 s

    简化的 Lens'签名现在应该可以减少恐惧了。如果您不得不猜测,什么是
    Lens' Person Age

    ?简单!这是一个 Lens,可以获取和设置 Age值内的 Person字段(记住镜头是 setter和getter 的组合吗?)。因此,您应用于 Getter s a的逻辑与您可以应用于 Lens' s a的逻辑相同。

    但是 s t a b部分呢?好吧,考虑一下这种类型:
    data Person a = { _idField :: a, address :: String }

    一个人可以通过一些识别值来识别并且具有年龄。假设您以名字来识别
    carolyn :: Person String
    carolyn = Person "Carolyn" "North Street 12"

    如果您有一个函数 toIdNumber :: String -> Int从字符串中生成一个ID号,该怎么办?您可能要这样做:
    λ> carolyn & idField %~ toIdNumber
    Person 57123 "North Street 12"

    但是如果使用 idField :: Lens' (Person String) String则不能,因为该镜头只能处理 String。它不知道将字符串转换为整数并将其粘贴在同一位置是什么意思。这就是为什么我们有 Lens s t a b的原因。

    我读到该签名的方式是“如果给我一个功能 a -> b,我将给您一个功能 s -> t”,其中 ab都指向镜头的目标,而 st则指向包含的数据结构。具体的例子:如果我们有
    idField :: Lens (Person String) (Person Int) String Int

    我们可以进行上面的转换。该镜头知道如何获取带有字符串id字段的 Person并将其变成带有 Int id字段的人。

    因此,从本质上讲, Lens s t a b可以读为“函数” (a -> b) -> (s -> t)。 “给我一个要在目标上执行的转换 (a -> b),以及一个包含该目标的数据结构 s,然后我将向您返回已应用该转换的数据结构 t。”

    当然,它实际上不是该函数–它比它更强大–但您可以通过将它提供给 overSetter,将其转化为该函数。

    盒子的内容

    盒子中的物品仅仅是每种光学器件中最常见和/或最核心的操作。他们的类型说明了他们的工作方式,我将举几个例子来说明我的意思。

    通常,最重要的项目是构造这种光学元件的方式。例如, Getter框中最上面的项是 to函数,该函数从任何函数 Getter构造一个 s -> a。如果您使用 Traversal函数,则可以从 Traversable免费获得 traverse

    接下来是常见操作。例如,您将在 view下找到 Getter,这是您使用 Getter从数据结构中获取内容的方式。在 Setter中,您发现 overset高了。

    (有趣的观察:大多数盒子似乎包含两个双重功能:一种创建光学部件的方式和一种使用它们的方式。有趣的是,它们通常具有几乎相同的类型签名,但彼此之间却发生了翻转。示例:
  • to :: (s -> a) -> Getter s a
  • view :: Getter s a -> (s -> a)


  • unto :: (b -> t) -> Review s t a b
  • review :: Review s t a b -> (b -> t)

  • 我现在注意到了一些有趣的东西。)

    我如何使用图形

    我通常不像我写这篇文章那样仔细地研究图形。通常,我只是偷看 SetterGetterTraversalLensPrism以及它们之间的关系,因为它们是我最常用的光学器件。

    当我知道需要执行某项操作时,通常会快速浏览一下该图形,以查看哪些框包含与我想要执行的操作类似的操作。 (例如,如果我有 data Gendered a = Masculine a | Feminine a,则 _Right与假设的 _Feminine相似。)确定后,我将进入这些模块的Haddocks(在本示例中为 Prism),搜索所需的操作。

    我如何了解光学

    我学习光学以及如何像学习所有东西一样使用它们。在光学是一个很好的解决方案时,我发现了一个真正的问题,我试图解决它。我尝试了,但我失败了,我再次尝试,我寻求帮助,尝试,尝试,尝试。最终我会成功。然后我尝试一些不同的东西。

    通过实际使用事物的方式来使用它们,我收集了很多有关它们如何工作的有用经验。

    奖金:个人误解

    在开始撰写本文之前,我以为您需要 Prism来处理 Maybe值,因为 Maybe类型是分支机构,不是吗?不完全的!至少不超过 List类型,您不需要 Prism来处理它。

    因为 Maybe类型是一个零个或一个元素的容器,所以实际上您只需要一个 Traversal即可处理它。当您有两个可以包含不同值的分支时,您开始需要 Prism的全部功能。 (但是,要构造 Maybe值,您仍然需要 Review。)

    仅在我开始非常仔细地阅读该图并探索模块以找出光学器件之间实际的形式差异时,我才意识到这一点。这是使用我的方法学习事物的缺点。只要它起作用,我就打开它。有时,这会导致回旋处事方式。

    关于haskell - 有人可以解释有关“镜头”库的图吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29742634/

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