你可能想要的是ST monad和mutable vector,而不是State Monad。
使用IO monad從類文件中讀取字節。
bytes <- readFile myClassFile
使用runST
對給定的字節運行ST
單子計算:
let result = runST $ transform bytes
的ST單子,您可以訪問mutable vectors,這是很多像C或Java數組。它們被整數索引,並且具有O(1)查找和修改。
transform :: [Char] -> ST s [Char]
transform bytes = do
mvec <- thaw $ fromList bytes
-- you can read a value at an index
val <- read mvec 0
-- and set a value at an index
write mvec 0 (val `xor` 0xff)
-- ...
-- turn it back into a list of bytes
vec <- freeze mvec
return $ toList vec
所以只要傳遞mvec
您的所有功能(這必須返回一個ST動作)左右,你就可以做任何你想要的字節數。
如果您不希望將其作爲參數傳遞,請考慮使用ReaderT
monad轉換使mvec
隱式地可供您的所有代碼使用。
transform bytes = do
-- ...
runReaderT other mvec
--- ...
other :: ReaderT (MVector s Char) (ST s) String
other = do
-- ...
-- grab the mvec when you need it
mvec <- ask
val <- lift $ read mvec 77
lift $ write mvec 77 (val * 363 - 28)
-- ...
return "Hi!"
當然,這都假設你需要隨機訪問字節。如果你不......那麼你可能不需要MVector
。
例如,如果你需要做的就是0xCAFEBABE
取代0xDEADBEEF
每一個實例,你可以只使用列表,無需ST單子:
let newBytes = intsToBytes . map (\i -> if i == 0xDEADBEEF then 0xCAFEBABE else i) $ bytesToInts bytes
http:// stackoverflow。com/questions/10230562/confusion-over-the-state-monad-code-on-learn-you-a-haskell – 2012-04-19 21:30:05
你會對字節做什麼樣的轉換?你插入和刪除塊?你需要隨機訪問?在擔心需要使用哪個monad之前,首先要弄清楚您需要哪種數據結構。這更重要。 – rampion 2012-04-20 11:02:23
此外,我猜測[這個問題]的答案(http://stackoverflow.com/questions/10253474/inject-a-function-into-a-java-class-file-using-haskell)將是對你有用。 – rampion 2012-04-20 21:44:57