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 == 2and inverse (*3) 12 == 4and之类的事情,以及无数其他令人难以置信的很棒的事情)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本着splitand的精神split':
inverse' :: (a -> b) -> (b -> a)
inverse' f (f x) = x
另一方面,这会导致以下错误:
Undefined data constructor `f'
我的问题:为什么 Curryf将潜在功能模式中的 in解释(f x)为数据构造函数,而++将(也是功能性)模式中的 in 解释(xs ++ ys)为函数名称?
换句话说,xsand ysinsplit' (xs ++ ys) = (xs,ys)似乎与 in 完全x类似inverse' f (f x) = x。
或者,如果与的类比split'不是很明显,请考虑prefix (xs ++ _) = xs等等orig (1 + x) = x,它们都可以编译和运行。
PS与原始帖子相比,我对名称和类型签名进行了一些调整,以使这个问题更容易理解。