我编写了一个函数(应该)获取无限的布尔列表并计算前n个元素的真值与假值之比:
prob n list = foldr (+) 0 (map boolToInt (take n list)) / n
where boolToInt b
| b == True = 1
| otherwise = 0
不幸的是,这不起作用:
No instance for (Fractional Int)
arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Int)
In the expression: foldr (+) 0 (map boolToInt (take n list)) / n
In an equation for `prob':
prob n list
= foldr (+) 0 (map boolToInt (take n list)) / n
where
boolToInt b
| b == True = 1
| otherwise = 0
Failed, modules loaded: none.
我尝试进行转换,但这不起作用:
prob n list = foldr (+) 0 (map boolToInt (take (fromIntegral (toInteger n)) list)) / n
where boolToInt b
| b == True = 1
| otherwise = 0
它正在编译,但是一旦我尝试调用该函数,我就会收到错误:
*Main> prob 50 toCoin1
<interactive>:1:6:
Ambiguous type variable `a0' in the constraints:
(Num a0) arising from the literal `50' at <interactive>:1:6-7
(Integral a0) arising from a use of `prob' at <interactive>:1:1-4
(Fractional a0) arising from a use of `prob' at <interactive>:1:1-4
Probable fix: add a type signature that fixes these type variable(s)
In the first argument of `prob', namely `50'
In the expression: prob 50 toCoin1
In an equation for `it': it = prob 50 toCoin1
有什么建议吗?
答案 0 :(得分:11)
你在错误的地方转换。尝试在整个fromRational
和foldr
周围粘贴n
。
prob n list = fromIntegral count / fromIntegral n
where count = foldr (+) 0 (map boolToInt (take n list))
boolToInt b
| b == True = 1
| otherwise = 0
哦,您的boolToInt
功能与fromEnum
专用Bool
相同。
prob n list = fromIntegral count / fromIntegral n
where count = foldr (+) 0 (map fromEnum (take n list))
您尝试做的根本问题是您对prob
的第一个参数强加了相互冲突的要求。您使用toInteger
约束n
为Integral
,但在/
中的使用要求它为Fractional
,并且没有类型Integral
}和Fractional
。
答案 1 :(得分:0)
Bool
是Enum
的一个实例,因此boolToInt
已提供fromEnum
。此外,foldr
正在执行sum
,因此整个功能可以简化为:
prob n list = (fromIntegral . sum . map fromEnum . take n) list / fromIntegral n
我们可以抽象出用于计算均值的代码(尽管这必须确定列表的长度,我们已经知道):
mean xs = (fromIntegral . sum) xs / (fromIntegral . length) xs
prob n = mean . map fromEnum . take n