我正在尝试将MIDI文件作为处理二进制文件的教育练习,但我遇到了麻烦。
当我读取曲目时,我想只抓取文件标题部分中声明的特定数量的曲目。这是我的代码,我试图解决它(虽然不起作用):
getMidi = do
header <- grabHeader
tracks <- grabTracks (numTracks header)
return (header, tracks)
grabTracks :: Integer -> Get [Track]
grabTracks numT = do
if numT == 0
then do
return []
else do
myTrack <- grabTrack
otherTracks <- grabTracks (numT-1)
return myTrack : otherTracks
grabTrack :: Get Track
grabTrack = do
chunkId <- getByteString 4
chunkSize <- getWord32be
events <- getLazyByteString (fromIntegral chunkSize)
return Track {trackSize=(fromIntegral chunkSize), eventData=events}
numT
是头文件中声明的曲目数。我想这样做有两个原因。
当我尝试编译它时,我收到此错误:
Couldn't match expected type `Get [a]' with actual type `[a0]'
In a stmt of a 'do' block: return myTrack : otherTracks
In the expression:
do { myTrack <- grabTrack;
otherTracks <- grabTracks (numT - 1);
return myTrack : otherTracks }
In a stmt of a 'do' block:
if numT == 0 then
do { return [] }
else
do { myTrack <- grabTrack;
otherTracks <- grabTracks (numT - 1);
return myTrack : otherTracks }
当我被迫使用像这样的列表连接时,我不知道如何制作Get
monad。谢谢你的时间!
答案 0 :(得分:0)
你需要括号
return (myTrack : otherTracks)
以便不将该行解析为
(return myTrack) : otherTracks
函数应用程序比任何中缀运算符都强大。
在第一个版本中,您返回Get
monad中的列表,在第二个版本中,您在do-block中有一个列表类型的表达式,其他语句是Get
s。