我正在使用haskell来实现一个涉及返回值的函数的模式,以及它们自己(或相同类型的函数).现在我已经实现了这样:
newtype R a = R (a , a -> R a)
-- some toy functions to demonstrate
alpha :: String -> R String
alpha str
| str == reverse str = R (str , omega)
| otherwise = R (reverse str , alpha)
omega :: String -> R String
omega (s:t:r)
| s == t = R (s:t:r , alpha)
| otherwise = R (s:s:t:r , omega)
Run Code Online (Sandbox Code Playgroud)
这些类型的函数的驱动力是一个称为级联的函数:
cascade :: (a -> R a) -> [a] -> [a]
cascade …Run Code Online (Sandbox Code Playgroud) 所以,我正在尝试实现这里描述的多变量ZipWithN .不幸的是,Paczesiowa的代码似乎是用ghc和HList的过时版本编译的,所以在试图理解它如何工作的过程中,我也将它移植到这两个版本的最新版本(ghc- 7.8.3和此时的HList-0.3.4.1).这很有趣.
无论如何,在中间函数的定义中,我遇到了谷歌没有帮助我修复一次的错误curryN'.在概念上,curryN'很简单:它采用类型级自然数N(或严格来说,该类型的值),以及f第一个参数是长度为HList的函数N,并返回一个N带有HList的-ary函数超出其第一个N参数,并将返回f应用于该HList.它是curry,但是多变量.
它使用三个辅助函数/类:
第一个是ResultType/ resultType,正如我在这里定义的那样. resultType将单个函数作为参数,并在将该函数应用于所需的参数之后返回该函数的类型.(严格地说,它再次返回该类型的未定义值).
例如:
ghci> :t resultType (++)
resultType (++) :: [a]
ghci> :t resultType negate
resultType negate :: (ResultType a result, Num a) => result
Run Code Online (Sandbox Code Playgroud)
(后一种情况,因为如果a恰好是类型的函数x -> y,则resultType必须返回y.因此它不适用于多态函数.)
后两个是和Eat/ eat和MComp/ mcomp,一起定义(连同curryN')在一个文件中(连同破碎curryN')像这样 …