Haskell中的状态单子
我正在用Haskell编写一个函数,它接受一个Java类文件,并编写另一个相同但包含一些修改的类文件。为此,我觉得我肯定需要一个状态monad来至少保存保存类文件所有字节的[Word8]。然而,在我对Haskell中的状态单子进行了所有的研究之后,我仍然很难弄清楚如何做到这一点。谁能给我指出正确的方向吗?我希望能够有一个[Word8](或者你知道,任何数据类型)在所有函数的范围内,并且我可以从函数中修改它。我知道这涉及到使用Haskell中的状态单子,haskell,functional-programming,monads,Haskell,Functional Programming,Monads,我正在用Haskell编写一个函数,它接受一个Java类文件,并编写另一个相同但包含一些修改的类文件。为此,我觉得我肯定需要一个状态monad来至少保存保存类文件所有字节的[Word8]。然而,在我对Haskell中的状态单子进行了所有的研究之后,我仍然很难弄清楚如何做到这一点。谁能给我指出正确的方向吗?我希望能够有一个[Word8](或者你知道,任何数据类型)在所有函数的范围内,并且我可以从函数中修改它。我知道这涉及到使用 state您可能想要的,不是state Monad,而是ST Mona
state您可能想要的,不是state Monad,而是ST Monad和可变向量 使用IO monad从类文件中读取字节
bytes <- readFile myClassFile
ST monad让您可以访问,这与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
当然,这都是假设您需要随机访问字节。如果你不。。。那么您可能不需要MVector
例如,如果您只需将0xDEADBEEF
的每个实例替换为0xCAFEBABE
,则可以只使用列表,而不需要ST monad:
let newBytes = intsToBytes . map (\i -> if i == 0xDEADBEEF then 0xCAFEBABE else i) $ bytesToInts bytes
您可能需要的是ST单子和可变向量,而不是状态单子 使用IO monad从类文件中读取字节
bytes <- readFile myClassFile
ST monad让您可以访问,这与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
当然,这都是假设您需要随机访问字节。如果你不。。。那么您可能不需要MVector
例如,如果您只需将0xDEADBEEF
的每个实例替换为0xCAFEBABE
,则可以只使用列表,而不需要ST monad:
let newBytes = intsToBytes . map (\i -> if i == 0xDEADBEEF then 0xCAFEBABE else i) $ bytesToInts bytes
我不确定您是否需要状态
单子。根据您想要进行的修改类型,您可以只将您想要修改的数据传递给每个想要修改它的函数<代码>状态通常用于除修改状态外还生成值的情况,即当您编写许多看起来像s->(s,a)
的函数时
首先尝试使用普通函数方法<代码>状态不是魔术,它只是让某些类型的代码更容易快速、简洁、正确地编写。你可以用它做任何事情,也可以不用它,只是有点乏味。我不确定你是否想要一个状态
单子。根据您想要进行的修改类型,您可以只将您想要修改的数据传递给每个想要修改它的函数<代码>状态通常用于除修改状态外还生成值的情况,即当您编写许多看起来像s->(s,a)
的函数时
首先尝试使用普通函数方法<代码>状态不是魔术,它只是让某些类型的代码更容易快速、简洁、正确地编写。你可以用它做的任何事情你也可以不用它,只是有点乏味。你要对字节做什么样的转换?您正在插入和删除块吗?你需要随机访问吗?在您考虑需要哪个monad之前,首先要弄清楚您需要什么样的数据结构。这更重要。而且,我猜的答案会对你有用。你将对字节做什么样的转换?您正在插入和删除块吗?你需要随机访问吗?在您考虑需要哪个monad之前,首先要弄清楚您需要什么样的数据结构。这更重要。而且,我猜的答案会对你有用。可变向量使你读写O(1),但插入和删除是O(n),所以我不确定这是最好的选择,除非你确定你没有改变类文件中的字节数。@DanBurton:你知道,我甚至没想到法罗斯会这么做。好球!可变向量使你读写O(1),但插入和删除是O(n),所以我不确定这是最好的选择,除非你确定你没有改变类文件中的字节数。@DanBurton:你知道,我甚至没想到Pha3drus会这么做。好球!谢谢,我最终只是使用了很多正常的函数来模拟状态变化。如果有人好奇,该项目涉及读取类文件,将其分成几个部分,并向方法中添加代码,以便在输入时打印出方法的名称。再次感谢!谢谢,我最终只是使用了很多正常的函数来模拟状态变化。如果有人好奇,该项目涉及读取类文件,将其分成几个部分,并向方法中添加代码,以便在输入时打印出方法的名称。再次感谢!