Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 我想不出这个简单的兴趣函数需要什么类型的签名_Haskell - Fatal编程技术网

Haskell 我想不出这个简单的兴趣函数需要什么类型的签名

Haskell 我想不出这个简单的兴趣函数需要什么类型的签名,haskell,Haskell,因此,我试图制作一个递归的简单兴趣函数,我一辈子都搞不清楚我需要使用什么类型的签名。这是我的密码: interest :: (Fractional a) => a-> a-> a-> a interest p r 0 = p interest p r t = (1 + (p/100))*interest p r (t-1) 这段代码给了我一个错误“无法推断(等式a)是由文字'0'引起的” 从上下文来看:分数a 受以下类型签名的约束: 兴趣::对于所有a.分数a=>a->

因此,我试图制作一个递归的简单兴趣函数,我一辈子都搞不清楚我需要使用什么类型的签名。这是我的密码:

interest :: (Fractional a) => a-> a-> a-> a
interest p r 0 = p
interest p r t = (1 + (p/100))*interest p r (t-1)
这段代码给了我一个错误“无法推断(等式a)是由文字'0'引起的” 从上下文来看:分数a 受以下类型签名的约束: 兴趣::对于所有a.分数a=>a->a->a->a“

但当我尝试将约束更改为(Eq a)时,它告诉我“可能的修复(分数a)”


有人能帮我吗?

第一句中对
0
的检查要求
a
也是
Eq
类型类的实例,因此您应该将此添加到签名中:

interest :: (Eq a, Fractional a) => a-> a -> a -> a
interest p r 0 = p
interest p r t = (1 + (p/100))*interest p r (t-1)
兴趣::(等式a,分数a)=>a->a->a->a 利息pr0=p
利息pr t=(1+(p/100))*利息pr(t-1)第一个子句中对
0
的检查要求
a
也是
Eq
类型类的实例,因此您应该将其添加到签名中:

interest :: (Eq a, Fractional a) => a-> a -> a -> a
interest p r 0 = p
interest p r t = (1 + (p/100))*interest p r (t-1)
兴趣::(等式a,分数a)=>a->a->a->a 利息pr0=p
兴趣pr t=(1+(p/100))*兴趣pr(t-1)值得一提的是,你可以通过这个“小技巧”找到类型,不要手动告诉类型,当你陷入这样的困境时,让Haskell替你想想:

interest p r 0 = p
interest p r t = (1 + (p/100))*interest p r (t-1) 
这样,代码就可以很好地编译,然后转到终端并执行以下操作:

:t interest
interest :: (Eq t1, Fractional t2, Num t1) => t2 -> t3 -> t1 -> t2
如果替换字母并删除额外的type class Num(因为在您的情况下需要分数实例),则与Willem的答案完全相同:

t1=>a;t2=>a;t3=>a

interest :: (Eq a, Fractional a) => a -> a -> a -> a

但是最好还是想想,你真正需要什么类型,为什么?

值得一提的是,你可以通过这个“小技巧”找到类型,不要手动告诉类型,当你陷入这样的困境时,让Haskell替你想想:

interest p r 0 = p
interest p r t = (1 + (p/100))*interest p r (t-1) 
这样,代码就可以很好地编译,然后转到终端并执行以下操作:

:t interest
interest :: (Eq t1, Fractional t2, Num t1) => t2 -> t3 -> t1 -> t2
如果替换字母并删除额外的type class Num(因为在您的情况下需要分数实例),则与Willem的答案完全相同:

t1=>a;t2=>a;t3=>a

interest :: (Eq a, Fractional a) => a -> a -> a -> a

但最好想想,你真正需要什么类型的约束以及为什么?

同时使用这两种约束?(顺便说一句,它们实际上被称为“约束”)是的,将其固定到约束上。同时,你说同时使用这两种约束是什么意思?类似这样的东西(等式a,分数a)?同时使用这两种约束?(顺便说一句,它们实际上被称为“约束”)是的,把它固定在约束上。你说两者都用是什么意思?像这样的(等式a,分数a)?这有时确实有用,但IMO仅适用于泛化、更改或简化类型签名:您有已经工作的代码,但签名是单态的,您希望使其具有多态性,或者某些依赖项更改了其签名,您希望进行调整,或者您有多余的约束。另一方面,对于新代码,我认为没有签名的原型制作更快是一个常见的初学者谬误。@leftaroundabout的确,这应该用来给你一些提示,最好是思考。这确实有时有用——但我只对概括、更改或简化类型签名有用:你有已经工作的代码,但签名是monomorphic,你想使它多态,或者某些依赖项更改了它的签名,你想适应,或者你有多余的约束。另一方面,对于新代码,初学者普遍认为没有签名的原型制作更快是错误的。@leftaroundabout确实,这应该给你一些提示,最好认为