Casting type in haskell, Fractional and Int
I wrote a function that (should) take an infinite list of booleans and calculate the ratio of True to False values ββover the first n elements:
prob n list = foldr (+) 0 (map boolToInt (take n list)) / n
where boolToInt b
| b == True = 1
| otherwise = 0
unfortunately what doesn't work:
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.
I tried to do the conversion, but that doesn't work either:
prob n list = foldr (+) 0 (map boolToInt (take (fromIntegral (toInteger n)) list)) / n
where boolToInt b
| b == True = 1
| otherwise = 0
It compiles, but as soon as I try to call the function, I get the error:
*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
Any suggestions?
source to share
You are converting to the wrong place. Try to just stick fromRational
around everyone foldr
and n
.
prob n list = fromIntegral count / fromIntegral n
where count = foldr (+) 0 (map boolToInt (take n list))
boolToInt b
| b == True = 1
| otherwise = 0
Oh, and your function is boolToInt
identical fromEnum
, specialized for Bool
s.
prob n list = fromIntegral count / fromIntegral n
where count = foldr (+) 0 (map fromEnum (take n list))
The main problem with what you were trying to do is to impose conflicting requirements on the first argument prob
. Your use is toInteger
limited n
as Integral
, but its use /
required it to be Fractional
, and there is no type that both Integral
and Fractional
.
source to share
Bool
- this is a copy Enum
, therefore it is boolToInt
already provided fromEnum
. It also foldr
does sum
, so the whole function can be simplified to:
prob n list = (fromIntegral . sum . map fromEnum . take n) list / fromIntegral n
We could abstract from the code to compute the average (although this would have to determine the length of the list we already know):
mean xs = (fromIntegral . sum) xs / (fromIntegral . length) xs
prob n = mean . map fromEnum . take n
source to share