Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell中的状态单子_Haskell_Functional Programming_Monads - Fatal编程技术网

Haskell中的状态单子

Haskell中的状态单子,haskell,functional-programming,monads,Haskell,Functional Programming,Monads,我正在用Haskell编写一个函数,它接受一个Java类文件,并编写另一个相同但包含一些修改的类文件。为此,我觉得我肯定需要一个状态monad来至少保存保存类文件所有字节的[Word8]。然而,在我对Haskell中的状态单子进行了所有的研究之后,我仍然很难弄清楚如何做到这一点。谁能给我指出正确的方向吗?我希望能够有一个[Word8](或者你知道,任何数据类型)在所有函数的范围内,并且我可以从函数中修改它。我知道这涉及到使用 state您可能想要的,不是state Monad,而是ST Mona

我正在用Haskell编写一个函数,它接受一个Java类文件,并编写另一个相同但包含一些修改的类文件。为此,我觉得我肯定需要一个状态monad来至少保存保存类文件所有字节的[Word8]。然而,在我对Haskell中的状态单子进行了所有的研究之后,我仍然很难弄清楚如何做到这一点。谁能给我指出正确的方向吗?我希望能够有一个[Word8](或者你知道,任何数据类型)在所有函数的范围内,并且我可以从函数中修改它。我知道这涉及到使用
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会这么做。好球!谢谢,我最终只是使用了很多正常的函数来模拟状态变化。如果有人好奇,该项目涉及读取类文件,将其分成几个部分,并向方法中添加代码,以便在输入时打印出方法的名称。再次感谢!谢谢,我最终只是使用了很多正常的函数来模拟状态变化。如果有人好奇,该项目涉及读取类文件,将其分成几个部分,并向方法中添加代码,以便在输入时打印出方法的名称。再次感谢!