【问题标题】:Does elm have haskell like lens or something similar?榆树有haskell之类的镜头或类似的东西吗?
【发布时间】:2016-07-02 15:28:55
【问题描述】:

在 haskell 中,我使用镜头库。榆树有类似的东西吗? 如果我有这个 elm 数据结构,我怎么能在test.a.b 上加 3。

test = {
  a = {
    b = 5
  }
 }

在 haskell 中我会写:test & a.b ~% (+3)。 在haskell我可以写makeLenses ''RecordName并自动生成镜头,elm有吗?

【问题讨论】:

  • 谷歌搜索“elm lens”得到elm-monocle(最后更新four months ago)和focus(最后更新one month ago)。
  • @Rhymoid 看来你得手动声明镜头
  • 据我所知,是的,您必须明确定义它们。虽然lens 可以通过 Template Haskell 为您生成 Haskell 代码,但 Elm 没有这样的元编程能力。

标签: elm


【解决方案1】:

有点。它有 Focus 库。它可以让你这样说:

Focus.update (a => b) ((+) 3) test

...将三个添加到test.a.b。它有两个让我想到的缺点。首先是您必须手工制作镜片。这没什么大不了的。对于您上面的test 记录,要手动创建镜头(或焦点),您首先需要一个 getter 函数,这很简单:

.a

然后是一个map函数,它可以将一个函数应用到a给定test

\f test = { test | a = f test.a }

现在您可以将这两者结合起来形成焦点:

a =
    Focus.create
        .a
        (\f test = { test | a = f test.a })

b做同样的事情:

b =
    Focus.create
        .b
        (\f a = { a | b = f a.b })

现在您可以将这两个焦点与(a => b) 结合起来,这样您就可以进行上面显示的Focus.update 调用。所以有一些样板,但这并不是什么大困难,您可以对自己的内容进行嵌套的获取/设置/更新。

更大的限制是,你不能做棱镜。因此,如果您的路径中涉及Maybe,您就会被阻止。回到以 long-long-longhand 方式进行嵌套更新。

为什么没有棱镜?因为他们需要更高级的类型,而 Elm 没有这些。 (还没有?)

所以答案是肯定的和否定的。您可以拥有类似 Lens 的东西,但不要指望 Haskell 镜头的全部功能。

更新:看来我的最后一点是错误的 - Monacle 提供了 Prisms。我不认为这是可能的。我站纠正!

【讨论】:

  • 单片眼镜似乎有焦点。
  • 谢谢@2426021684!我已经更新了我的答案,现在我需要去了解它是如何可能的。 :-D
猜你喜欢
  • 1970-01-01
  • 2017-07-15
  • 2014-09-22
  • 2010-11-29
  • 2020-03-26
  • 2011-10-18
  • 2023-03-09
  • 2011-04-04
  • 1970-01-01
相关资源
最近更新 更多