榆树 - 生成随时间变化的随机数列表

时间:2014-07-25 16:02:45

标签: random signals elm

我试图让一列随机数每秒都在变化,但我得到不同的错误信息:

import Random

main = flow down 
[ asText (Random.range 0 100 (every second))  
, asText (Random.range 0 100 (every second))
]

给出了解析错误。我的方括号[有什么问题?

Parse error at (line 5, column 1):
unexpected '['
expecting newline, spaces or end of input

缩进也许?

一旦我缩进,该示例确实编译但我得到的是<signal>而不是实际的数字

main = flow down 
  [ asText (Random.range 0 100 (every second))  
  , asText (Random.range 0 100 (every second))
  ]

信号

lift

最后,当我尝试使用lift时,它给了我其他的困惑

main = flow down 
  [ lift asText (Random.range 0 100 (every second))  
  , lift asText (Random.range 0 100 (every second))
  ]

错误消息是我的lift类型错误。

Type error on line 5, column 5 to 9:
       lift

  Expected Type: Signal Element
    Actual Type: Element

没有flow down只是一个列表

如果我忘了流下来,它仍然没有合作:

main = lift asText
  [  (Random.range 0 100 (every second))  
  ,  (Random.range 0 100 (every second))
  ]

我收到_List预期的错误消息:

Type error between lines 5 and 7:
       [Random.range 0 100 (every second),
        Random.range 0 100 (every second)]

  Expected Type: _List
    Actual Type: Signal

我正确使用Random.range吗?我没有从原来的例子中改变它:

如何与liftflow down合作?

2 个答案:

答案 0 :(得分:5)

这是一个适用于0.15 [EDIT:和0.16]的答案,目前是Elm的最新版本。由于写了Joe的答案,因此对Random库进行了大修,以使用纯随机数生成器。伪随机数是确定性的:除非你改变初始种子,否则每次运行总是相同的。

我们从导入开始:无聊但必要,然后使用随机库定义一些常量。

import Graphics.Element exposing (flow, down, show, Element)
import Time exposing (fps)
import Random

gen = Random.int 0 100
gen2 = Random.pair gen gen
seed0 = Random.initialSeed 42

接下来,我们定义一个状态类型,包含随机种子和要显示的数字。我以为我们想要两个;对于常量长度列表,请使用Random.list n gen。我们还使用记录构造函数语法(以及两个“随机”数字)定义初始状态。

type alias State = {seed : Random.Seed, first : Int, second : Int}
state0 = State seed0 36 89

现在我们定义一个每秒运行一次的步骤函数。在这里,我们剥离两个随机数并将它们与新种子一起存储。请注意,我们每次使用一个新种子,将其链接到下一个种子。

step : a -> State -> State
step _ state =
  let
    ((first, second), seed') = Random.generate gen2 state.seed
  in
    State seed' first second

现在我们使用foldp来引入状态,以实际运行该步骤函数。

state : Signal State
state = Signal.foldp step state0 (fps 1)

我们定义一个纯渲染函数。这里没有信号。

render : State -> Element
render state =
    flow down [show state.first, show state.second]

最后我们将渲染功能映射(以前提升)到状态。

main = Signal.map render state

如果您连接灰色框并删除插页式评论,您将获得一个有效的Elm 0.15程序。但请注意,它似乎是CPU密集型的。

答案 1 :(得分:3)

有几件事情在这里发生:

正如您所料,在第一部分中,您会遇到编译器不喜欢的缩进问题。

下一个例子是有效的,因为列表中的两件事实际上就是信号。但是,这不是你想要的。相反,您想打印出符号。

以下是提升Random.range的简单示例:

import Random

main = asText <~ (Random.range 0 10 (every second))

这将每秒显示0到1之间的值。这与lift的工作方式有关。它的类型是(a -> b) -> Signal a -> Signal b。每当第二个参数的信号发生变化时,它就会使用值运行指定的函数。

因此,正在尝试的第三件事的编译错误是抱怨函数flow期望列表的内容为Element,但它们实际上是Signal Element

你在那里做的最后一件事是行不通的,因为lift期待Signal作为其第二个参数,但你改为给它[Signal]

你真的想要这样的东西:

import Random

main = lift2 randomcolumn (Random.range 0 100 (every second)) (Random.range 0 100 (every second))

randomcolumn x y = flow down [asText x,
                          asText y]

http://share-elm.com/sprout/53d28d73e4b07afa6f983534

希望这有帮助!