是否有可能编写函数来返回其签名取决于构造器函数的参数的函数?
具体来说,我正在细化我编写的基本递归的实现。我希望像工厂一样的函数为数值参数生成一个函数,该函数可以在元组或长度等于为数值参数传递的参数的列表上工作。目前,我正在处理像pr 1 2 [0,5,13]
这样的案例,这是一个从原始递归的角度来看是无效的语句,在运行时通过Either
处理。
pr :: (Show a) => Int -> Int -> [a] -> Either String a
pr i k args
| 1 <= i && i <= k && length args == k = Right $ args!!(i-1)
| i <= 0 = Left "first argument of pr needs to be greater or equal to 1"
| k < i = Left "first argument of pr needs to be lesser or equal to the second argument"
| length args /= k = Left $ "pr expected "++(show k)++" arguments, got "++(show $ length args)++": pr "++(concat[show i, " ", show k, " ", show args])
但我想在编译时以某种方式捕捉这种情况,从我想用它实现的正式系统的角度来看,这是一个编译时错误--将更多的参数传递给一个函数,而不是它的域指定的。
这在某种程度上是可能的吗?如果不是,那么正确的方法是获得应该是无效语句的编译时错误。
发布于 2018-04-04 15:41:21
你想要的是一个大小的矢量。它就像一个列表,但是除了它的元素的类型之外,它还被类型级别的自然数参数化。
黑客上的大小矢量包是您所需要的。碰巧,您要实现的函数是这个库中的last
函数。
请注意,每次调用last
时,您都必须证明编译器的参数向量的大小至少为1。可以通过在源代码中构造向量(例如,编译器将理解1 :- 2 :- Nil
的大小为2),或者如果向量是在运行时获得的--可能是通过从列表中转换获得的--您将不得不编写一个函数,如果它没有元素,或者构造至少一个大小的向量,即为某些n
构造一个类型级别的大小S n
。
如果您不熟悉依赖类型的编程(这是一个包含这一点的范例,还有更多),我建议您先看看一些教程。例如,这个职位是一个很好的例子,它包括如何从零开始实现向量并为它们编写函数。
一句谨慎的话,学习和使用可靠的类型化编程是令人兴奋的,上瘾的,但也耗费时间。因此,如果您想将精力集中在手头的任务上,那么您可能希望暂时接受运行时检查。
https://stackoverflow.com/questions/49661648
复制相似问题