- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想写一个函数
forkos_try :: IO (Maybe α) -> IO (Maybe α)
它接受命令x
。 x 是一个命令式操作,它首先改变状态,然后检查该状态是否困惑。 (它不会执行任何外部操作,这需要某种操作系统级沙箱来恢复状态。)
x
计算结果为 Just y
,forkos_try
返回 Just y
。forkos_try
回滚状态,并返回Nothing
。在内部,它应该fork()
到线程parent
和child
中,x
在上运行> child
。
x
成功,child
应继续运行(返回 x
的结果),而 parent
应终止parent
应继续运行(返回 Nothing
),而 child
应死亡问题:如何编写具有与 forkos_try
等效或更强大语义的内容? 注意-- 状态突变(由x
)位于外部库中,并且无法在线程之间传递。因此,保持哪个线程事件的语义很重要。
正式地,“继续运行”意味着“执行一些延续rest::Maybe α -> IO ()
”。但是,该延续并未在代码中明确保留。
对于我的情况,我认为(暂时)可以使用 forkOS
以不同的风格编写它(这需要运行整个计算 child
) ,因为我可以为 rest
编写一个显式表达式。但是,令我困扰的是,我无法弄清楚如何使用原始函数 forkOS
来做到这一点——人们会认为它足够通用以支持任何特定情况(这可能会表现为一种高-级别 API,如 forkos_try
)。
编辑 - 如果问题仍然不清楚,请参阅带有显式 rest
的示例代码 [ http://pastebin.com/nJ1NNdda ].
附:我已经有一段时间没有写并发代码了;希望我对 POSIX fork()
的了解是正确的!提前致谢。
最佳答案
如果你明确地对状态进行建模,事情就会变得更容易推理。
someStateFunc :: (s -> Maybe (a, s))
-- inside some other function
case someStateFunc initialState of
Nothing -> ... -- it failed. stick with initial state
Just (a, newState) -> ... -- it suceeded. do something with
-- the result and new state
对于不可变状态,“回滚”很简单:只需继续使用 initialState
即可。而且“不回滚”也很简单:只需使用 newState
即可。
所以...我从你的解释中假设这个“外部库”执行一些不平凡的 IO 效果,但这些效果仅限于一些已知且可逆的操作(修改文件、IORef 等)。有些事情是无法逆转的(发射导弹、写入标准输出等),所以我在这里看到两个选择之一:
当然,这两者实际上都是同一个做法:fork the world。一个世界负责行动,另一个世界不负责。如果行动成功,那么那个世界就会继续;否则,另一个世界仍将继续。您建议通过构建 forkOS
来实现此目的,这将克隆程序的整个状态,但这不足以处理例如文件修改等问题。请允许我建议一种更接近简单的不可变状态的方法:
tryIO :: IO s -> (s -> IO ()) -> IO (Maybe a) -> IO (Maybe a)
tryIO save restore action = do
initialState <- save
result <- action
case result of
Nothing -> restore initialState >> return Nothing
Just x -> return (Just x)
这里您必须提供一些数据结构s
,以及一种从所述数据结构保存
和恢复
的方法。这使您可以灵活地执行您认为必要的任何克隆。 (例如,save
可以将某个文件复制到临时位置,然后restore
可以将其复制回来并删除临时文件。或者save
可以复制某些 IORef 的值,然后 restore
可以将值恢复。)这种方法可能不是最有效的,但非常简单。
关于haskell - 如何在 Haskell 中实现 fork try-catch?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9497195/
我刚刚遇到了一个非常奇怪的行为。这是代码: // So far everything's fine val x: Try[Try[Unit]] = Try(Try{}) x: scala.util.T
“输出”是一个序列化的 OpenStruct。 定义标题 try(:output).try(:data).try(:title) 结束 什么会更好? :) 最佳答案 或者只是这样: def title
我有以下元组 - (t1,t2) :(Try,Try) 我想检查两者是否成功或其中之一是否失败,但避免代码重复。像这样的东西: (t1,t2) match { case (Success(v1),Su
是否必须放置内部 try-with-resources 或其中一个 try-with-resources 中的所有内容都会自动关闭? try (BasicDataSource ds = Bas
有一点特殊,尝试创建一段 try catch 代码来处理 GoogleTokenResponse,但编译器在 try 时抛出异常错误。有什么想法吗? 错误信息: | Loading Grails 2.
它几乎可以在所有语言中找到,而且我大部分时间都在使用它。 我不知道它是内部的,不知道它是如何真正起作用的。 它如何在任何语言的运行时在 native 级别工作? 例如:如果在 try 内部发生 sta
为什么在 readFile2() 中我需要捕获 FileNotFoundException 以及稍后由 close( ) 方法,并且在 try-with-resources(inside readfi
我正在使用 Apache POI 尝试读取 Word 文件,但即使您使用过 Apache POI,这仍然应该是可以回答的。在 HWPF.extractor 包中有两个对象:WordExtractor
如果try-catch的catch block 中抛出异常,那么finally block 会被调用吗? try { //some thing which throws error } cat
这个问题已经有答案了: What's the purpose of try-with-resources statements? (7 个回答) 已关闭 3 年前。 我一直在查看代码,并且已经看到了对
这个问题已经有答案了: What's the purpose of try-with-resources statements? (7 个回答) 已关闭 3 年前。 我一直在查看代码,并且已经看到了对
我正在使用 Try::Tiny尝试捕捉。 代码如下: use Try::Tiny; try { print "In try"; wrongsubroutine(); # undefi
我想知道这样的代码是否会在抛出异常后总是中断而不继续运行,因此代码不会继续执行第二个 temp.dodaj(b)。 Avto *a = new Avto("lambo",4); Avt
我知道在try子句中必须有一个与资源关联的变量声明。 但是除了被分配一个通常的资源实例化之外,它是否可以被分配一个已经存在的资源,例如: public String getAsString(HttpS
我有一个写的方法。此方法仅扫描用户输入的整数输入。如果用户输入一个字符值,它将抛出一个输入不匹配异常,这是在我的 Try-Catch 语句中处理的。问题是,如果用户输入任何不是数字的东西,然后抛出异常
我注意到这不会编译: PrintWriter printWriter = new PrintWriter("test.txt"); printWriter.append('a'); printWrit
我经常看到人们写这样的代码: try: some_function() except: print 'something' 当我认为这样做更干净时: try: some_functio
该应用程序将在第二个显示器上正常显示内容。问题是当我旋转 iPad 时内容不会在 iPad 上旋转。 看过: http://developer.apple.com/library/ios/#qa/qa
我正在学习 java,我发现我不喜欢的一件事通常是当我有这样的代码时: import java.util.*; import java.io.*; public class GraphProblem
我使用 C++ 有一段时间了,对普通的 try/catch 很熟悉。但是,我现在发现自己在 Windows 上,在 VisualStudio 中编码以进行 COM 开发。代码的几个部分使用了如下内容:
我是一名优秀的程序员,十分优秀!