使用 Elm 生成随机 UUIDv4
Generate random UUIDv4 with Elm
我正在尝试在循环中生成随机 UUID 的 v4:
randomUuid =
-- TODO: find a way to generate random uuid for variableId
updatedVariables =
group.variables |> List.map (\variable -> { variable | id = randomUuid })
我阅读了 elm/random and elm/uuid 的文档,但找不到如何在不使用种子的情况下生成 UUID。
我唯一能做的就是:
newUuid : Random.Seed -> ( String, Random.Seed )
newUuid seed =
seed
|> Random.step UUID.generator
|> Tuple.mapFirst UUID.toString
我看到 elm/random 是一个 independentSeed
函数,但我无法让它生成种子。
我试图用 randomUuid
实现的等效节点是:
const { uuid } = require('uuidv4');
const randomUuid = uuid();
我觉得我可能在这里遗漏了 Elm 中的一些重要概念,但我自己无法理解。任何帮助或指示将不胜感激。
生成随机值是一种效果,因此纯语言不能只执行它。
但是,有一个纯粹的随机版本,它使用随机种子。这些具有 属性 每次你使用相同的种子生成一个值时,你都会得到相同的值 - 因此这只是一个纯计算并且在纯上下文中完全没问题。
Elm 允许你像 Cmd
一样执行效果,你 return 从你的 init
和 update
功能。因此,您的一个选择是始终 return Random.generate GotANewUUID UUID.generator
在 需要它之前,然后在处理 GotANewUUID
消息时执行计算。
另一种选择是跟踪随机种子。您可以从 Random.initialSeed
的确定性开始(可能不是您想要的 UUID,因为它们在您程序的每个 运行 上都完全相同),或者在您的 init
函数中你returnRandom.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)
我正在尝试在循环中生成随机 UUID 的 v4:
randomUuid =
-- TODO: find a way to generate random uuid for variableId
updatedVariables =
group.variables |> List.map (\variable -> { variable | id = randomUuid })
我阅读了 elm/random and elm/uuid 的文档,但找不到如何在不使用种子的情况下生成 UUID。
我唯一能做的就是:
newUuid : Random.Seed -> ( String, Random.Seed )
newUuid seed =
seed
|> Random.step UUID.generator
|> Tuple.mapFirst UUID.toString
我看到 elm/random 是一个 independentSeed
函数,但我无法让它生成种子。
我试图用 randomUuid
实现的等效节点是:
const { uuid } = require('uuidv4');
const randomUuid = uuid();
我觉得我可能在这里遗漏了 Elm 中的一些重要概念,但我自己无法理解。任何帮助或指示将不胜感激。
生成随机值是一种效果,因此纯语言不能只执行它。
但是,有一个纯粹的随机版本,它使用随机种子。这些具有 属性 每次你使用相同的种子生成一个值时,你都会得到相同的值 - 因此这只是一个纯计算并且在纯上下文中完全没问题。
Elm 允许你像 Cmd
一样执行效果,你 return 从你的 init
和 update
功能。因此,您的一个选择是始终 return Random.generate GotANewUUID UUID.generator
在 需要它之前,然后在处理 GotANewUUID
消息时执行计算。
另一种选择是跟踪随机种子。您可以从 Random.initialSeed
的确定性开始(可能不是您想要的 UUID,因为它们在您程序的每个 运行 上都完全相同),或者在您的 init
函数中你returnRandom.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)