Why actual type is Double?

4049 views haskell
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?

answered question

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.

1 Answer

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

Have an answer?

JD

Please login first before posting an answer.