Wolfgang Jeltsch撰写的关于基于 Haskell 的KiCS2实现Curry的相当引人入胜的 2013 年介绍性文章A Taste of Curry为组合器提供了以下定义inverse
:
inverse :: (a -> b) -> (b -> a)
inverse f y | f x =:= y = x where x free
(注意:对于不熟悉库里的路人来说,这会做类似inverse (+1) 3 == 2
and inverse (*3) 12 == 4
and之类的事情,以及无数其他令人难以置信的很棒的事情)inverse htmlHodeToStr == parseHtmlNode
此外,它还提供了 2 个替代但等效的(非确定性)split :: [a] -> ([a], [a])
函数定义:
split :: [a] -> ([a],[a])
split list | front ++ rear =:= list = (front,rear)
和
split' :: [a] -> ([a],[a])
split' (xs ++ ys) = (xs,ys)
以及其他一些颇具启发性的定义,但是超出了本文的范围。
然而,我的想法使我尝试了一种替代的、紧凑的定义,inverse
本着split
and的精神split'
:
inverse' :: (a -> b) -> (b -> a)
inverse' f (f x) = x
另一方面,这会导致以下错误:
Undefined data constructor `f'
我的问题:为什么 Curryf
将潜在功能模式中的 in解释(f x)
为数据构造函数,而++
将(也是功能性)模式中的 in 解释(xs ++ ys)
为函数名称?
换句话说,xs
and ys
insplit' (xs ++ ys) = (xs,ys)
似乎与 in 完全x
类似inverse' f (f x) = x
。
或者,如果与的类比split'
不是很明显,请考虑prefix (xs ++ _) = xs
等等orig (1 + x) = x
,它们都可以编译和运行。
PS与原始帖子相比,我对名称和类型签名进行了一些调整,以使这个问题更容易理解。