首页 > 解决方案 > 随机执行函数列表中的函数

问题描述

=== 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但我不确定如何实现这种伪随机性。任何帮助,将不胜感激!

标签: haskell

解决方案


你说,

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

说起来很奇怪,因为没有“否则”——如果你的东西()有时返回,它永远不会返回任何东西(),因为没有其他具有相同类型的值!特别是,这意味着不可能到达_您案件的分支。

在您的语言中,如此处所示,语句基本上不计算数据。也许您应该将Selection构造函数更改为采用 an[(HVal, HStatement)]而不是 an [HStatement](表示返回一些有趣的计算对,您可以case在该语句的某个适当分支中执行该语句case),或者将语句计算的类型修改为更丰富的类型比()


推荐阅读