fromNotes :: [(Char, Int)] -> [Double]
fromNotes = map freq
where
freq (x,y) = 440 * 2**((midi x y - midi 'A' 4)/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)
代码给出错误:
* Couldn't match type `Int' with `Double'
Expected type: [(Char, Int)] -> [Double]
Actual type: [(Char, Double)] -> [Double]
据我所知,问题出在midi x y - midi 'A' 4
中。
但是Haskell为什么说实际类型是Double?
答案 0 :(得分:8)
fromNotes
返回一个[Double]
,所以freq
必须返回Double
,所以2**((midi 'A' 4 - midi x y)/12)
必须是Double
,所以midi
必须返回Double
,所以o * 12
必须是Double
,所以midi
的第二个参数必须为Double
,所以y
中的midi x y
必须是Double
,所以freq
必须将Double
作为其元组的第二部分。您几乎可以在该链中的任何步骤使用fromIntegral :: Int -> Double
来解决问题。立刻完成操作可能是最简单的,例如
freq (x, y) = ... midi x (fromIntegral y) ...