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