上面提到的中缀函数以及各种常见的数据类型的透镜组,在Hackage上面有几个著名的函数库已经能帮助你定义好了。而且,生成自定义数据类型的透镜组的工作也不需要你手动完成。因为Haskell中有模板(template)编程的功能,只要你提供了使用记录语法定义好的数据类型,一句话就可以让编译器自动帮你生成记录中每一项的透镜组。

而实际上,透镜组的类型往往要比本文中提供的复杂一些。例如,在lens函数库里,透镜组是这样定义的:

type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
type Lens' s a = Lens s s a a

这里我们把数据操作过程的类型从a -> f a扩展到了a -> f b,表示在操作子数据的时候,类型有可能已经发生了改变,于是大类型s也可能发生相应的改变,变成类型t。而对于本章中出现的简单的数据操作的情况,我们用Lens' s a表示上述操作的一个特例。关于Lens,其实可以说的还有很多,这里只介绍了一些基础内容。在第29章中,我们会再次提到这个类型,并详细讲述如何通过模板构造镜片组。

此外,我们还展示了Haskell中一个实现函数的常用思路:先写出你要的函数类型,然后根据类型去推导,利用已知的函数,去一点点拼凑出想要的函数,而这个函数最终的底层实现过程,在函数被实现之后再慢慢分析即可。很多时候,当类型确定的时候,函数实现就已经确定了。所以在Haskell中,设计类型是编程过程中非常重要的一步,这是其他编程语言很难带来的体验,而编译器强大的类型推断和检查,能够保证你的思路不会出错。当然,想要写出(a -> f a) -> b -> f b这样的类型,需要敏锐的洞察力和灵感,这正是函数式编程的美妙之处。

评论

本文目前还没有评论……

我要评论

需要登录后才能发言
登录未成功,请修改提交。

× 451
× 1756
× 2435
× 934
× 1
× 1
× 1191
× 0
× 1
× 0
× 2
× 1
× 3
× 3
× 2750
× 817
× 1104