gpt4 book ai didi

random - 初始化榆树应用程序的正确方法是什么

转载 作者:行者123 更新时间:2023-12-03 13:23:54 24 4
gpt4 key购买 nike

Elm 的文档 Random模块状态:

A good way to get an unexpected seed is to use the current time. http://package.elm-lang.org/packages/elm-lang/core/1.1.0/Random



但是,我看不到如何在 FRP 应用程序中执行此类初始化逻辑的好例子。我应该对什么信号使用react?如何以最少的代码和最大的清晰度做到这一点。

最佳答案

有不同的方法可以做到这一点。每个都有它自己的好处。我会给你三个我知道的,每个都有一个类似的例子。

1) 添加时间码输入

您可以做的一件事是为程序的输入增加时间。一个使用每秒当前时间作为随机数的小程序示例:

import Time
import Time (Time, second)
import Text (asText)
import Mouse
import Signal
import Signal (Signal, (<~), (~))
import Random
import Random (Seed)
import Graphics.Element (Element)

randomInt : Seed -> Int
randomInt seed = seed |> (Random.generate <| Random.int 1 10) |> fst

otherInput : Signal (Int,Int)
otherInput = Mouse.position

timeSeed : Signal Seed
timeSeed = Random.initialSeed << round <~ Time.every second

inputs : Signal (Seed,(Int,Int))
inputs = (,) <~ timeSeed ~ otherInput

update : (Seed, (Int,Int)) -> (Int,Int) -> (Int,Int)
update (seed,(x,y)) (x',y') =
let num = randomInt seed
in (x-x'-num,y'-y+num) -- this update function is nonsense

main : Signal Element
main = asText <~ Signal.foldp update (0,0) inputs

如果您无论如何都需要时间作为输入,并根据此时间对其他输入进行采样,这是最简单的方法。 (如果您已经为此使用 Time.fps ,请使用 Time.timestamp 获取实际时间)

2) 启动时有信号

如果您通常不需要时间作为程序的输入,那么之前的解决方案并不理想。您可能更喜欢使用程序的开始时间来初始化程序状态,而不必在程序运行的其余时间忽略时间标记。

使用 signal-extra package 可能最容易做到这一点。 *。使用 Signal.Time.startTime 得到一个不滴答但只有程序的开始时间作为初始值的信号。使用 Signal.Extra.foldp' 因此您可以使用输入的初始值。
import Time
import Time (Time, second)
import Text (asText)
import Mouse
import Signal
import Signal (Signal, (<~), (~))
import Random
import Random (Seed)
import Graphics.Element (Element)
import Signal.Extra as SignalE
import Signal.Time as Time

randomInt : Seed -> (Int,Seed)
randomInt seed = (Random.generate <| Random.int 1 10) |> fst

otherInput : Signal (Int,Int)
otherInput = Mouse.position

startTimeSeed : Signal Seed
startTimeSeed = Random.initialSeed << round <~ Time.startTime

inputs : Signal (Seed,(Int,Int))
inputs = (,) <~ startTimeSeed ~ otherInput

update (x,y) (seed,(x',y')) =
let (num,seed') = randomInt seed
in (seed',(x-x'-num,y'-y+num))

main : Signal Element
main = asText <~ SignalE.foldp' (snd >> update) identity inputs

*我可能有偏见,因为我是链接包的作者。但我不知道其他提供相同功能的软件包。

3) 使用端口启动时

如果你发现以前的解决方案不满意,因为你有这个不变的 Signal要添加到您的输入中,此解决方案适合您。这里我们使用 JavaScript interop获取程序启动时间,Elm 将接受它作为一个常量值(没有 Signal)。 Elm 代码如下所示:
import Time
import Time (Time, second)
import Text (asText)
import Mouse
import Signal (Signal, (<~))
import Random
import Random (Seed)
import Graphics.Element (Element)

port startTime : Float

randomInt : Seed -> (Int,Seed)
randomInt seed = (Random.generate <| Random.int 1 10) |> fst

startTimeSeed : Seed
startTimeSeed = Random.initialSeed <| round startTime

update (x,y) (seed,(x',y')) =
let (num,seed') = randomInt seed
in (seed',(x-x'-num,y'-y+num))

main : Signal Element
main = asText <~ Signal.foldp update (startTimeSeed, (0,0)) Mouse.position

那么这里有什么缺点呢?您需要编写一些 JavaScript。代替标准
<script>Elm.fullscreen(Elm.<YourModule>)</script>

,您的 html 文件中需要这样的内容:
<script>Elm.fullscreen(Elm.<YourModule>, {startTime: Date.now()})</script>

如果您选择这种方式,那么使用 JavaScript 中的随机数作为初始种子可能是个好主意。我读过这在密码学上更安全(免责声明:我对密码学知之甚少)。所以你会有一个 port aRandomNumber : Int{aRandomNumber: Math.floor((Math.random() - 0.5) * 4294967295)} .

关于random - 初始化榆树应用程序的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28606248/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com