我有以下代码:
betaRest :: Int -> [Int] -> Int
betaRest n prevDigits | n == 0 = (length prevDigits)
| otherwise = (sum (map (betaRest (n - 1)) [0..9]))
betaFirst :: Int -> Int
betaFirst n | n == 0 = 0
| otherwise = (betaRest (n - 1) [1..9])
它给了我下面的错误,我不知道为什么。
1)任何实例(枚举[INT])从算术序列所产生的 '0 .. 9'
2)没有实例从字面产生(民[INT])“0”
难道哈斯克尔认为,与“..”运营商做的事情是枚举? 但是,为什么是不是有,下面是4条线(用“[1..9]”)这则该行的错误?
编辑:我想要的代码做的是这样的(在程序上):
int betaRest(int n, int[] prevDigits) {
if (n == 0) return prevDigits.length;
else {
sum = 0;
foreach prevDigit in prevDigits {
sum += betaRest(n - 1, [0..9]);
}
return sum;
}
}
int betaFirst(int n) {
if (n == 0) return 0;
else return betaRest(n - 1, [1..9]);
}
因此,betaFirst(1)== 9,和betaFirst(2)== 90是,有人可能希望建议用于产生这样的公式,但我要某种类型的过滤器添加到[0..9 ],从而降低的范围内。
您传递betaRest
来map
。 地图是(a -> a) -> [a] -> [a]
所以[Int]
列表中,您传递它想要的Int -> Int
功能。 但部分地施加betaRest
是[Int] -> Int
。
至于[0..9]
其类型是(Enum t, Num t) => [t]
和它的翻译成enumFromTo 0 9
应用。 所以编译器想通您的错误周围的其他方法:如果你定义特殊的Num
和Enum
实例的列表,所以[0..9]
变成为int的名单列表,那么你的应用程序将是有意义的。
但我认为你想使用inits
或tails
的功能。 让我们知道你想达到的,所以我们可以帮助解决什么。
一个最小的修复程序会增加prevDigits
作为参数map
和使用lambda抽象忽略未使用的prevDigit
:
| otherwise = sum (map (\prevDigit -> betaRest (n - 1) [0..9]) prevDigits)
(sum (map (betaRest (n - 1)) [0..9]))
让我们减少括号的数量,以便更好地能够看到发生了什么。
sum (map (betaRest (n - 1)) [0..9])
的说法sum
是
map (betaRest (n-1)) [0 .. 9]
现在, betaRest :: Int -> [Int] -> Int
,部分应用函数的,因此类型是
betaRest (n-1) :: [Int] -> Int
因此,我们可以推断出类型
map (betaRest (n-1)) :: [[Int]] -> [Int]
但传递的参数来map (betaRest (n-1))
是[0 .. 9]
其类型为
[0 .. 9] :: (Num a, Enum a) => [a]
的Num
约束来自使用一个整数文字,和所述的Enum
从使用的约束enumFromTo
功能(在其语法糖形式[low .. high]
)。 顺便指出,作为参数传递给期望类型的参数的函数[[Int]]
指型变量a
必须被实例化为[Int]
然后需要被检查的制约,即,实例[Int]
为Num
和Enum
必须抬起头来。 这些都不存在,因此错误消息。
我不知道你的程序的例子是你真正想要的东西,
int betaRest(int n, int[] prevDigits) {
if (n == 0) return prevDigits.length;
else {
sum = 0;
foreach prevDigit in prevDigits {
sum += betaRest(n - 1, [0..9]);
}
return sum;
}
}
该foreach
循环更容易(和更有效)表示为
sum = prevDigits.length * betaRest(n-1, [0 .. 9]);
因此对于foreach
是有道理的,应该有一个依赖prevDigit
在循环体。
翻译哈斯克尔会
betaRest n prevDigits
| n == 0 = length prevDigits
| otherwise = length prevDigits * betaRest (n-1) [0 .. 9]
-- or with the loop, with the small improvement that `betaRest (n-1) [0 .. 9]
-- is only computed once (if the Haskell implementation is sensible)
-- | otherwise = sum $ map (const $ betaRest (n-1) [0 .. 9]) prevDigits
但如上所述,我怀疑这真的是你想要的。