拉姆达风格的思考:镜头

1.第一步
2.结合功能
3.部分使用(咖喱)
4.声明式编程
5.典型符号
6.不变性与对象
7.不变性和数组
8.镜片
9.结论


这篇文章是关于函数式编程的一系列文章的第八篇,名为Ramda Style Thinking。


第六部分和第七部分中,我们学习了如何以声明性和不变的方式读取,更新和转换对象和数组元素的属性。


Ramda还提供了用于执行这些操作的更通用的工具,称为镜头。


什么样的镜片?


镜头将吸气功能和设定功能组合为一个机构。 Ramda提供了一组用于处理镜头的功能。


我们可以将镜头视为专注于大型数据结构的特定部分的事物。


如何制作镜头?


在Ramda中创建镜头的主要方法是使用镜头功能。 lens具有吸气功能和设定功能,并返回新的镜头。


 const person = { name: 'Randy', socialMedia: { github: 'randycoulman', twitter: '@randycoulman' } } const nameLens = lens(prop('name'), assoc('name')) const twitterLens = lens( path(['socialMedia', 'twitter']), assocPath(['socialMedia', 'twitter']) ) 

在这里,我们使用proppath方法作为我们的assocPath函数,并使用assocassocPath作为我们的assocPath函数。


请注意,我们使用属性名称和这些函数所需属性的路径复制了参数。 幸运的是, Ramda为最常见的镜头使用情况提供了很酷的快捷方式: lensProplensPathlensIndex


  • lensProp创建一个聚焦于对象属性的镜头
  • lensPath创建一个镜头,聚焦于对象的附加属性
  • lensIndex创建一个聚焦在数组元素上的镜头

我们可以使用lensProplensPath重写上述镜头:


 const nameLens = lensProp('name') const twitterLens = lensPath(['socialMedia', 'twitter']) 

它简单得多,并且消除了重复项。 在实践中,我发现我几乎不需要原始的lens功能。


我该怎么办?


好吧,太好了,我们制造了一对镜片。 现在我们该怎么办?


Ramda提供三种镜头功能。



 view(nameLens, person) // => 'Randy' set(twitterLens, '@randy', person) // => { // name: 'Randy', // socialMedia: { // github: 'randycoulman', // twitter: '@randy' // } // } over(nameLens, toUpper, person) // => { // name: 'RANDY', // socialMedia: { // github: 'randycoulman', // twitter: '@randycoulman' // } // } 

请注意, setover返回整个对象,并带有镜头聚焦的更改值。


结论


如果我们有一个非常复杂的数据结构,希望在调用代码时从中抽象出来,那么镜头就可以派上用场了。 除了提供每种可用属性的结构或提供吸气剂,设置器和变压器之外,我们还可以提供透镜。


客户代码可以通过使用viewsetover来进一步使用我们的数据结构,而无需链接到数据结构的确切形式。


下一个


现在我们知道Ramda提供的很多信息; 通常,足以完成我们在程序中执行的所有操作。 本系列的最后一篇文章概述了已研究的内容,并提到了我们可能希望自己探索的其他一些主题。

Source: https://habr.com/ru/post/zh-CN415035/


All Articles