# 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
```

```

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?

+3

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`

.

+11

source

`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
```