我正在写一个函数,但我找不到合适的解决方案。我该如何解决这个问题:
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)
错误是
interactive:33:1:
No instance for (Fractional a0) arising from a use of ‘it’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance HasResolution a => Fractional (Fixed a)
-- Defined in ‘Data.Fixed’
instance Integral a => Fractional (Ratio a)
-- Defined in ‘GHC.Real’
instance Fractional Double -- Defined in ‘GHC.Float’
...plus one other
In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
输入集
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
答案 0 :(得分:3)
问题是Haskell只能对相同类型的值进行算术运算。当您执行x + y
或x * y
或x == y
时,x
和y
必须具有相同的类型。
第二个问题是Haskell的数值类型(主要)分为两类,即整数和分数。只有整数类型(例如Integer
)支持div
和mod
,并且只有小数类型(例如Double
)支持/
。
您的代码尝试将div
,mod
和/
与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
此处所有输入(val
,x
,y
)均为Integer
,这使div
和mod
正常工作,结果是Double
。每当需要小数(对于/
并且要添加到递归findLoot
调用的结果)时,fromIntegral
用于将Integer
转换为Double