Clojure中类似于Haskell的“Scrap Your Boilerplate”(SYB)的方法

11

我在Haskell中发现了一个有趣的库,叫做Scrap Your Boilerplate,基于Simon Peyton Jones的一篇论文,该库似乎是在函数式编程语言中编写可以更新大型、深度嵌套数据结构的有效方法。它使代码如下所示:

incS :: Float -> Salary -> Salary
incS k (S s) = S (s * (1+k))

increase :: Float -> Company -> Company
increase k = everywhere (mkT (incS k))

这个功能有效地增加了一个固定比例k的薪水,适用于可能非常大和复杂的公司数据结构中的每个人。

是否有等效的库或方法来实现Clojure中同样的编程风格?

例如,我如何编写与上面使用的示例相当的Clojure代码:

(defn increase [company k]
  (everywhere-in company (transform-map-values :salary #(* % (+ 1 k))))

2
SYB论文是与合著者Ralf Lämmel的工作延续,他使用(不同的)合著者Joost Visser将Stratego嵌入到Haskell中。要在Clojure中更新嵌套结构,您需要SYB的“遍历控制”方面而不是其数据类型通用性方面,因此您可以将问题扩大以询问是否有人已将Stratego嵌入Clojure中。我不了解Clojure,一些网络搜索似乎表明还没有人这样做。在Scheme中肯定有Stratego遍历的嵌入,这应该比SYB更容易移植,我自己就写过一个。 - stephen tetley
2
我不知道SYB,但也许clojure.walk是你正在寻找的东西? - Jouni K. Seppänen
2个回答

4

在Clojure中,最接近这个概念的可能是“in”函数(assoc-in、update-in、dissoc-in)。

这些函数允许你在Clojure中进行深度嵌套的精确更改。在Haskell中没有这些函数的等效物,因为它们严重依赖于动态类型。


1
当这个问题首次提出时,它们还不存在,但我认为转换器使编程风格类似。基本上,可转换过程实现了一定的函数集,而转换器可以使用这些函数遍历任何可转换过程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接