haskell - 随机执行函数列表中的函数
问题描述
=== HStatement 的评估(如果和选择栏)===
evalStatement_ :: Env -> HStatement -> IOThrowsError ()
evalStatement_ env (Do cond expr) = evalVal env cond >>= \x -> case x of
HBool False -> return ()
HBool True -> do
traverse_ (evalStatement_ env) expr
evalStatement_ env (Do cond expr)
evalStatement_ env (Skip skip) = return ()
evalStatement_ env (Print (HString val)) = getVar env val >>= \x -> liftIO $ putStrLn $ show x
evalStatement_ env (Print val) = evalVal env val >>= \x -> liftIO $ putStrLn $ show x
evalStatement_ env (Eval val) = do
result <- evalVal env val
return ()
=== 选择和如果的表示 ===
parseIf :: Parser HStatement
parseIf = do
string "("
cond <- parseArith
string ")->"
spaces
expr <- many1 $ parseStatements
spaces
return $ If (cond, expr)
parseSelection :: Parser HStatement
parseSelection = do
_ <- string "if"
spaces
selection <- many1 $ parseIf
spaces
_ <- string "fi"
spaces
return $ Selection selection
注意:如果选择的评估更改为以下,则程序运行并终止并给出输出:
evalStatement_ env (Selection if_ selection fi_ n) = evalStatement_ env (selection !! randIdx n) >>= \res -> if res == ()
then return ()
else return ()
然而,输出给出了介于 1 和 10 之间的不同数量的偶数。例如,一个输出将打印所有偶数,而另一个输出将打印数字 6。
tldr; 有没有办法从函数列表中随机执行随机函数,如果结果不理想,请重新执行该函数以执行随机函数,直到结果理想?
我正在尝试编写一个在函数列表中执行随机条目的函数。If (HVal, HStatement) -- If (Guard,Statement)
列表中的每个条目都按以下方式构造:
HVal:
data HVal
= HInteger Integer
HBool Bool
HString String
HList [HVal]
Length HVal
Arith HVal Op HVal
Assign String HVal
deriving (Eq, Read)
HStatement:
data HStatement
= Eval HVal
| Print HVal
| Do HVal [HStatement]
| If (HVal, [HStatement])
| Selection [HStatement]
deriving (Eq, Read)
到目前为止,我尝试的是根据我昨天的问题Asyncs race
使用功能。我对此的想法是,如果在一个列表中存在一个由 n 个条目组成的列表,这些条目构造为真正的守卫。If (HVal, HStatement)
race
由于. raceAll
_ IO
我通过考虑使用随机数生成器重新设计了该方法。
所以现在我正在生成保护语句对列表的随机索引。我执行此列表中的条目并执行案例分析。如果输出是,()
那么我再次调用该函数,否则我返回输出。为此,我使用了两个函数,其中selection
表示if's
:
evalStatement_ env (If (cond, expr)) = evalVal env cond >>= \x -> case x of
HBool False -> return ()
HBool True -> traverse_ (evalStatement_ env) expr
evalStatement_ env (Selection selection) = evalStatement_ env (selection !! randIdx 1) >>= \res -> case res of -- randIdx produces an index between 0 and 1 representing the two branches in the selection block that could be taken
() -> evalStatement_ env (Selection selection)
_ -> return $ res
randIdx n = unsafePerformIO (getStdRandom (randomR (0, n - 1)))
以下面的程序为例:
f := [1 2 3 4 5 6 7 8 9 10]
n := 0
N := len(f)
Do (n < N)->
a := f.n
if ((a % 2) = 0)-> print(a)
((a % 1) = 1)-> print(a)
fi
n := n + 1
Od
这里发生的是程序根本没有输出并且没有终止。我期望发生的是在 0 和可能的分支数减一之间生成一个随机索引。然后将对其进行评估,如果它返回一个值,则将采用该值,否则,如果它是单元类型,则会生成一个新的随机索引并使用该索引。
我可以执行程序但是如果选择的函数定义是traverse_ (evalStatement_ env) selection
但我不确定如何实现这种伪随机性。任何帮助,将不胜感激!
解决方案
你说,
如果输出是,
()
那么我再次调用该函数,否则我返回输出。
说起来很奇怪,因为没有“否则”——如果你的东西()
有时返回,它永远不会返回任何东西()
,因为没有其他具有相同类型的值!特别是,这意味着不可能到达_
您案件的分支。
在您的语言中,如此处所示,语句基本上不计算数据。也许您应该将Selection
构造函数更改为采用 an[(HVal, HStatement)]
而不是 an [HStatement]
(表示返回一些有趣的计算对,您可以case
在该语句的某个适当分支中执行该语句case
),或者将语句计算的类型修改为更丰富的类型比()
。
推荐阅读
- c++ - Breakpad 的 dump_syms 无法正常工作
- excel - 如果在第一列中未找到 VLOOKUP 多列
- typescript - 描述在 Typescript、Mocha 和 VSCode 上未定义异常
- ag-grid - AG 网格除显示行总计外,还显示百分比行总计
- google-cloud-platform - 创建 Bigtable 副本集群会产生度量错误
- c# - 在 IIS 上运行的 ASP.net 上的超长 TTFB
- php - 如何在 Twig 的标题下显示名称列表
- pandas - 处理`read_csv`的本地时间变化缓慢的熊猫
- ruby-on-rails - NoMethodError: nil:NilClass 的未定义方法 `<'
- opengl - GL_DEPTH_CLAMP 无效(反向 z)