Haskell 没有因使用‘;它’;
我正在写一个函数,但找不到合适的解决方案。如何解决此问题:Haskell 没有因使用‘;它’;,haskell,Haskell,我正在写一个函数,但找不到合适的解决方案。如何解决此问题: findLoot val [] = 0 findLoot val ((x:y:[]):xs) | val == 0 = 0.0 | val < y = ((val*x)/y) | val > y = ((div val y)*x) + (findLoot (mod val y) xs) 输入集是 Input 1:
findLoot val [] = 0
findLoot val ((x:y:[]):xs) | val == 0 = 0.0
| val < y = ((val*x)/y)
| val > y = ((div val y)*x) + (findLoot (mod val y) xs)
输入集是
Input 1:-
val = 50
((x:y:[]):xs) = [[120, 30], [100,50],[60, 20]]
Output 1:-
180.0000
Input 2:-
val = 10
((x:y:[]):xs) = [[500,30]]
Output 2:-
166.6667
问题是Haskell只能对相同类型的值进行算术运算。如果执行
x+y
或x*y
或x==y
,则x
和y
必须具有相同的类型
第二个问题是Haskell的数值类型(主要)分为两类,整数和小数。只有整数类型(如Integer
)支持div
和mod
,只有分数类型(如Double
)支持/
您的代码尝试将div
、mod
和//code>与x
、y
和val
一起使用,这迫使Haskell查找一种既为分数又为整数的类型。这样的类型是不存在的
下面是一个可能的解决方案:
findLoot :: Integer -> [[Integer]] -> Double
findLoot val [] = 0
findLoot val ((x:y:[]):xs) | val == 0 = 0.0
| val < y = fromIntegral (val * x) / fromIntegral y
| val > y = fromIntegral (div val y * x) + findLoot (mod val y) xs
findLoot::Integer->[[Integer]]->Double
FindRoot val[]=0
findLoot val((x:y:[]):xs)| val==0=0.0
|valy=from积分(div val y*x)+findLoot(mod val y)xs
这里所有的输入(val
,x
,y
)都是整数
s,这使得div
和mod
工作,结果是Double
。每当需要小数时(用于/
和添加到递归findLoot
调用的结果中),from integral
用于从整数
转换为双精度看起来像可怕的单态限制(谷歌这个术语)-它试图确定您的号码类型,但无法确定其中一种。@Bergi有办法修改吗?我想不出一个合适的解决方案。添加一个显式类型findLoot::Fractional a=>a->[a]->a
@Bergi一旦我添加了这个,我在加载时就发现错误,无法将预期的类型“a”与实际类型“[a]匹配“a”是一个刚性类型变量,由FindRoot的类型签名绑定::分数a=>a->[a]->因为div
和/
看起来都是错误的。你的号码是什么类型的?您可能只需要/
(浮点)或只需要div
(整数除法)。需要注意的是,您对类型的显式声明将使编译器提供更多信息错误。良好的实践是值得的。
findLoot :: Integer -> [[Integer]] -> Double
findLoot val [] = 0
findLoot val ((x:y:[]):xs) | val == 0 = 0.0
| val < y = fromIntegral (val * x) / fromIntegral y
| val > y = fromIntegral (div val y * x) + findLoot (mod val y) xs