考虑下面的Haskell代码。
data Keypress = Keypress Int Char
getSeq :: Keypress -> [Char]
getSeq (Keypress i c) = replicate i c
有没有办法以无点形式写getSeq
?
getSeq
的定义和它的模式匹配非常相似,似乎可以使用currying或monads之类的方法来避免指定i
和c
参数。但是,pointfree.io不能解析getSeq
的无点输出,我认为是由于模式匹配。
这可能吗?
3条答案
按热度按时间jdzmm42g1#
定义一个catamorphism通常是有用的,尤其是对于具有多个构造函数的递归数据类型,这是一种在为每个可能的构造函数给定一个函数时折叠数据结构的方法。
例如,对于
Bool
,变质作用为且对于
Either
,它是更高级的退化是列表的退化,你可能以前见过:
foldr
!我们通常不会这么想(至少我不会),但
foldr
是一种退化:只要您为[a]
的两个构造函数中找到的值提供“处理程序,”它就可以处理模式匹配和递归地解构列表:[]
的一种情况,根本不需要参数:只有b
类型的值(x:xs)
的案例。这个案例采用一个参数表示x
,即列表的头部,还有一个参数表示递归折叠尾部的结果,即b
类型的值。对于只有一个构造函数的类型,退化就不那么令人兴奋了,但是我们可以很容易地为
Keypress
类型定义一个构造函数:在某种程度上,退化允许您抽象出函数定义的模式匹配部分,之后您可以只使用那些不再需要直接接触底层数据类型的函数。
定义了一次通用函数之后,您可以多次使用它,以实现您所希望的任何无点函数。
gz5pxeao2#
正如所写的,没有。但如果你愿意,你可以修复它:
然后
并且可以被转换成
cclgggtu3#
如果没有一点样板文件,您就无法做到这一点,但是
lens
可以为您生成样板文件,所以这可能是您将获得的最接近的结果。从
Control.Lens.TH
使用makePrisms
将生成一个Iso
,它本质上是单构造函数数据类型上的一级模式匹配。方便的是,Iso
是双向的,所以你可以对它们执行view
(取出值,就像模式匹配一样)和review
(把值放回,就像正常使用构造函数一样)。使用
makePrisms
和view
,可以用无点的方式写getSeq
:这样更好吗?我不知道。代码中的模式匹配在我看来很好,但是如果你已经在使用
lens
,这个版本可能更适合你。