随机执行函数列表中的一个函数



=== HStatement的求值(bar if and selection) ===

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

N。B:如果选择的求值改为如下,则程序运行并终止,并给出输出:

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)where

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函数。我的想法是,如果在一个构造为If (HVal, HStatement)的列表中存在一个包含n个条目的列表,那么在一个仅包含HStatements列表的列表上运行race函数,这些列表的守卫值被求值为true,将返回执行真正守卫中最快的函数。

由于IO的约束,试图将raceAll行为合并到我的代码库中对我来说太困难了。我通过考虑使用随机数生成器来修改方法。

所以现在我正在生成guard语句对列表的随机索引。我执行该列表中的条目并执行案例分析。如果输出为(),则再次调用该函数,否则返回输出。为此,我使用了两个函数,其中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和可能分支数- 1之间生成。然后这个将被求值,如果它返回一个值,这个将被取;否则如果它是单位类型,一个新的随机索引将被生成并被使用。

我可以执行程序,但是,如果选择的函数定义是traverse_ (evalStatement_ env) selection,但我只是不确定如何实现这种伪随机性。任何帮助将不胜感激!

你说,

如果输出是(),则再次调用该函数,否则返回输出。

这是一件奇怪的事情,因为没有"否则"-如果你的东西有时返回(),它永远不会返回()以外的任何值,因为没有其他值具有相同的类型!特别是,这意味着不可能到达您的案例的_分支。

在这里所示的语言中,语句基本上不计算数据。也许你应该改变你的Selection构造函数,用[(HVal, HStatement)]代替[HStatement](表示返回一些有趣的东西的计算对,你可以在case上与语句一起在case的某个适当分支中执行),或者修改语句计算的类型,使其比()更丰富。

最新更新