Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Random 初始化elm应用程序的正确方法是什么_Random_Functional Programming_Frp_Elm - Fatal编程技术网

Random 初始化elm应用程序的正确方法是什么

Random 初始化elm应用程序的正确方法是什么,random,functional-programming,frp,elm,Random,Functional Programming,Frp,Elm,Elm随机模块的文档说明: 获取意外种子的一个好方法是使用当前时间。 然而,我并没有看到一个在FRP应用程序中如何执行这种初始化逻辑的好例子。我应该对什么信号作出反应?如何以最少的代码和最大的清晰度做到这一点。有不同的方法可以做到这一点。每个人都有自己的好处。我会给你我知道的三个例子,每一个都有一个相似的例子 1) 添加一个计时器输入 您可以做的一件事是为程序的输入添加时间。一个使用每秒当前时间的随机数的微型程序示例: import Time import Time (Time, second

Elm
随机
模块的文档说明:

获取意外种子的一个好方法是使用当前时间。


然而,我并没有看到一个在FRP应用程序中如何执行这种初始化逻辑的好例子。我应该对什么信号作出反应?如何以最少的代码和最大的清晰度做到这一点。

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

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
*我可能有偏见,因为我是链接包的作者。但我不知道还有其他软件包提供相同的功能

3) 在启动时使用端口 如果您发现以前的解决方案不令人满意,因为您没有更改
信号
以添加到您的输入中,则此解决方案适合您。这里我们使用它来获取程序启动时间,Elm将接受它作为一个常量值(no
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
导入时间
导入时间(时间,秒)
导入文本(asText)
导入鼠标
输入信号(信号,((Int,Seed)
randomInt seed=(Random.generate fst
星体:种子

starttimesed=Random.initialSeed如果您使用的是StartApp,则需要使用自定义HTML文件

<script type="text/javascript">
    var yourPgm = Elm.fullscreen(Elm.Main, {startTime: Date.now()});
</script>

我重新编写了上面@Apanatshka的第三个示例,试图得到更简单的代码,感觉更像标准体系结构,至少在Mike Clark的培训视频中可以看到,并在Elm 0.16下运行。下面是我提出的重构版本:

module PortBasedRandom where

import Mouse
import Signal exposing (Signal, map)
import Random exposing (Seed)
import Graphics.Element exposing (Element, show)

port primer : Float


firstSeed : Seed
firstSeed =
  Random.initialSeed <| round primer


type alias Model =
  { nextSeed : Seed
  , currentInt : Int
  }


initialModel : Model
initialModel =
  { nextSeed = firstSeed
  , currentInt = 0
  }


randomInt : Model -> Model
randomInt model =
  let
      (i, s) = Random.generate (Random.int 1 10) model.nextSeed
  in
      { model | nextSeed = s, currentInt = i }


update : (Int, Int) -> Model -> Model
update (_, _) model =
  randomInt model


main : Signal Element
main =
  Signal.foldp update initialModel Mouse.position
    |> map (\m -> show m.currentInt)
模块PortbasedAndom,其中
导入鼠标
导入信号(信号、映射)
导入随机曝光(种子)
导入图形。元素公开(元素,显示)
端口底漆:浮子
第一种子
头号种子=
随机种子模型
随机点模型=
让
(i,s)=Random.generate(Random.int 1 10)model.nextSeed
在里面
{model | nextSeed=s,currentInt=i}
更新:(Int,Int)->模型->模型
更新(u,u)模型=
随机点模型
主:信号元件
主要=
Signal.foldp更新初始模型Mouse.position
|>映射(\m->show m.currentInt)
这需要HTML文件中的特殊帮助,因此这里有一个包含两个示例的文件:

<html>
  <head>
    <title></title>
    <script src="port_based_random.js"></script>
  </head>
  <body>
    <p>Move your mouse to generate new random numbers between 1 and 10 inclusive.</p>
    <script>Elm.fullscreen(Elm.PortBasedRandom, {primer: Date.now()})</script>
    <script>Elm.fullscreen(Elm.PortBasedRandom, {primer: Math.floor((Math.random() - 0.5) * 4294967295)})</script>
  </body>
</html>

移动鼠标以生成介于1和10之间(含1和10)的新随机数

全屏(Elm.portbasedAndom,{primer:Date.now()}) Elm.fullscreen(Elm.PortBasedRandom,{primer:Math.floor((Math.random()-0.5)*4294967295)}
对于像我一样从谷歌来到这里的人来说,这只是一个更新:现在建议使用
标志
而不是
端口
。其他答案中的代码现在甚至不会编译

HTML

<script>
  var app = Elm.Main.fullscreen({myRandomValue: Date.now()});
</script>


我们现在正在Elm邮件列表上讨论这个问题:答案质量仍然很低。您应该直接在代码中添加一些示例。@谢谢您的反馈-我在我的答案中添加了一些示例代码。
startTimeSeed : Seed
startTimeSeed = Random.initialSeed <| round startTime

app =
  StartApp.start
    { init = (init startTimeSeed, Effects.none)
    , update = update
    , view = view
    , inputs = []
    }
init : Seed -> List Int
init seed = fst <| Random.generate intList seed
intList : Random.Generator (List Int)
intList =
    Random.list 5 (Random.int 0 100)
module PortBasedRandom where

import Mouse
import Signal exposing (Signal, map)
import Random exposing (Seed)
import Graphics.Element exposing (Element, show)

port primer : Float


firstSeed : Seed
firstSeed =
  Random.initialSeed <| round primer


type alias Model =
  { nextSeed : Seed
  , currentInt : Int
  }


initialModel : Model
initialModel =
  { nextSeed = firstSeed
  , currentInt = 0
  }


randomInt : Model -> Model
randomInt model =
  let
      (i, s) = Random.generate (Random.int 1 10) model.nextSeed
  in
      { model | nextSeed = s, currentInt = i }


update : (Int, Int) -> Model -> Model
update (_, _) model =
  randomInt model


main : Signal Element
main =
  Signal.foldp update initialModel Mouse.position
    |> map (\m -> show m.currentInt)
<html>
  <head>
    <title></title>
    <script src="port_based_random.js"></script>
  </head>
  <body>
    <p>Move your mouse to generate new random numbers between 1 and 10 inclusive.</p>
    <script>Elm.fullscreen(Elm.PortBasedRandom, {primer: Date.now()})</script>
    <script>Elm.fullscreen(Elm.PortBasedRandom, {primer: Math.floor((Math.random() - 0.5) * 4294967295)})</script>
  </body>
</html>
<script>
  var app = Elm.Main.fullscreen({myRandomValue: Date.now()});
</script>
type alias Model = {
  mySeed : String
}

type alias Flags = {
  myRandomValue : String
}

init : Flags -> ( Model, Cmd Msg )
init flags =
  {
    mySeed = flags.myRandomValue
  }
main : Program Flags Model Msg
main = programWithFlags
  {
    view = view,
    init = init,
    update = update
  }