生成随机值是一种效果,因此纯语言不能仅仅执行它。
但是,有一个纯粹的随机性版本,它使用随机种子。它们的特性是,每次使用相同的种子生成值时,都会得到相同的值 - 因此这只是一个纯计算,在纯上下文中完全可以。
Elm 允许您以Cmd 的形式执行效果,这是您从init 和update 函数返回的东西。所以你有一个选择是总是在你需要它之前返回Random.generate GotANewUUID UUID.generator,然后在你处理GotANewUUID msg 时执行你的计算。
另一个选项是跟踪随机种子。你要么从一个确定性的Random.initialSeed 开始(可能不是你想要的UUID,因为它们在你的程序的每次运行中都是完全相同的),或者在你的init 函数中返回Random.generate GotNewSeed Random.independentSeed。然后将种子存储在模型中。
每次需要生成新的 UUID 时,请使用上面的 newUuid 函数,确保存储新的种子。
这是一个例子:
import Random
import UUID
type alias Thing =
{ id : String
-- , some other stuff
}
type alias Model =
{ seed : Random.Seed
, stuff : List Thing
}
type Msg
= GotNewSeed Random.Seed
| AddAThing Thing
| AddABunchOfThings (List Thing)
init : () -> (Model, Cmd Msg)
init flags =
({ seed = Random.initialSeed 567876567
-- Let's start with a deterministic seed
-- so you don't need to deal with Maybe Seed later
, stuff = []
}, Random.generate GotNewSeed Random.independentSeed
)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
GotNewSeed seed ->
({model | seed = seed}, Cmd.none)
AddAThing thing ->
let
(newId, newSeed) =
newUuid model.seed
in
({ model | stuff = { thing | id = newId } :: model.stuff
, seed = newSeed }
, Cmd.none
)
AddABunchOfThings things ->
let
(newStuff, newSeed) =
List.foldl (\thing (stuff, seed) ->
newUuid seed
|> Tuple.mapFirst (\id ->
{ thing | id = id } :: stuff
)
) (model.stuff, model.seed) things
in
({model | stuff = newStuff, seed = newSeed}, Cmd.none)