# Why actual type is Double?

4049 views
7

``````fromNotes :: [(Char, Int)] -> [Double]
fromNotes = map freq
where
freq (x,y) =  440 * 2**((midi 'A' 4 - midi x y)/12)
midi c o = o * 12 + getIndex c s 0 + 12
s = "CcDdEFfGgAaB"
getIndex c (x:xs) i
| c == x    = i
| otherwise = getIndex c xs (i+1)
``````

The code gives the error:

``````* Couldn't match type `Int' with `Double'
Expected type: [(Char, Int)] -> [Double]
Actual type: [(Char, Double)] -> [Double]
``````

From what i can tell the problem is in `midi 'A' 4 - midi x y`.

But why is Haskell saying the actual type is a Double?

Because the `(**)` has as type `Floating a => a -> a -> a`

@WillemVanOnsem then what other operator can i use?

`(^)` works for integral types.

You probably also should replace `(...) / 12` with `div (...) 12`.

but that gives ` No instance for (Fractional Int)`

see above, your `div` forces you to make it a `Fractional`. So given the number in the numerator is dividable by `12`, you can use `div`.

2

1. `fromNotes` returns a `Double`, so
2. `freq` must return a `Double`, so
3. `2**((midi 'A' 4 - midi x y)/12)` must be a `Double`, so
4. `midi` must return a `Double`, so
5. `o * 12` must be a `Double`, so
6. the second argument to `midi` must be a `Double`, so
7. the `y` in `midi x y` must be a `Double`, so
8. `freq` must take a `Double` as the second part of its tuple.

You can use `fromIntegral :: Int -> Double` at almost any step in that chain to fix things up. It's probably simplest to do it right away, as in

``````freq (x, y) = ... midi x (fromIntegral y) ...
``````

posted this