榆树有像镜头一样的类似物吗?

242*_*684 6 elm

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

test = {
  a = {
    b = 5
  }
 }
Run Code Online (Sandbox Code Playgroud)

在哈斯克尔,我会写:test & a.b ~% (+3).在haskell,我可以编写makeLenses ''RecordName并自动生成镜头,榆树有吗?

Kri*_*ins 5

有点.它有Focus库.这会让你说出类似的话:

Focus.update (a => b) ((+) 3) test
Run Code Online (Sandbox Code Playgroud)

...添加三个test.a.b.它有两个缺点,让人想起.首先,你必须手工制作镜片.这不是什么大问题.对于test上面的记录,要手动创建镜头(或焦点),首先需要一个getter函数,这是微不足道的:

.a
Run Code Online (Sandbox Code Playgroud)

然后是map函数,它可以将函数应用于a给定test:

\f test = { test | a = f test.a }
Run Code Online (Sandbox Code Playgroud)

现在,您可以将这两者结合起来进行聚焦:

a =
    Focus.create
        .a
        (\f test = { test | a = f test.a })
Run Code Online (Sandbox Code Playgroud)

做同样的事情b:

b =
    Focus.create
        .b
        (\f a = { a | b = f a.b })
Run Code Online (Sandbox Code Playgroud)

现在你可以将这两个焦点组合在一起,(a => b)然后让你进行Focus.update上面显示的调用.所以有一些样板,但它没有太大的困难,你可以对你内心的内容进行嵌套的获取/设置/更新.

更大的限制是,你不能做棱镜.因此,如果Maybe您的路径中涉及到某个问题,则会被阻止.回到做嵌套更新的长期漫长的方式.

为什么没有棱镜?因为他们需要更高的kinded类型,而Elm没有那些.(然而?)

所以答案是肯定的和否定的.你可以拥有镜头般的东西,但不要指望Haskell镜头的全部功能.

更新:在我的最后一点看起来我错了 - Monacle提供棱镜.我认为不可能.我纠正了!