如何将第二个模具添加到此elm effects示例中?
我是Elm的新手,一直在看下面的示例(注意,这是在较新的0.17体系结构下,其中操作现在是命令): 接下来的挑战是向示例中添加第二个骰子,以便单击按钮为每个骰子滚动一个新值。我的想法是将模型更改为包含两个单独的值,每个骰子对应一个值如何将第二个模具添加到此elm effects示例中?,elm,Elm,我是Elm的新手,一直在看下面的示例(注意,这是在较新的0.17体系结构下,其中操作现在是命令): 接下来的挑战是向示例中添加第二个骰子,以便单击按钮为每个骰子滚动一个新值。我的想法是将模型更改为包含两个单独的值,每个骰子对应一个值 type alias Model = { dieFace1 : Int , dieFace2 : Int } 在到达更新块之前,这一切都很正常。我不知道如何更新随机数生成器来创建两个值。这个函数对我来说有点混乱 type
type alias Model =
{ dieFace1 : Int
, dieFace2 : Int
}
在到达更新块之前,这一切都很正常。我不知道如何更新随机数生成器来创建两个值。这个函数对我来说有点混乱
type Msg
= Roll
| NewFace Int Int
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Roll ->
**(model, Random.generate NewFace (Random.int 1 6))** <-- not sure what to do here
NewFace newFace1 newFace2 ->
(Model newFace1 newFace2, Cmd.none)
type Msg
=滚动
|新面孔整型
更新:Msg->Model->(Model,Cmd-Msg)
更新msg模型=
味精案例
滚动->
**(模型,Random.generate NewFace(Random.int 1 6))**
(型号newFace1 newFace2,Cmd.none)
Random.generate函数的文档有点浅显-
生成:(a->msg)->生成器a->Cmd msg
创建将生成随机值的命令
这是处理两个骰子的正确方法,还是有更好的方法?我是一个elm noob,请友好点:)
Random.int
是一个原始的生成器,它给你一个随机整数。你需要一个生成器,它正好给你两个随机整数
随机数生成器可以从更原始的生成器构建,以创建更复杂的生成器。幸运的是,Elm正好有这样一个函数,它允许您为元组的每个部分指定所需的两个生成器
让我们将模具生成器拉入其自身功能,以避免重复我们自己的操作:
dieGenerator:Random.Generator Int
柴油发电机=
Random.int 16
现在我们可以构建另一个生成器,它为我们提供一对模具的随机值:
diePairGenerator:Random.Generator(Int,Int)
双发电机=
随机双介质发生器
因为我们正在处理一组整数,所以让我们将Msg
对newfaceintint
的定义更新为NewFaces(Int,Int)
。这将使您的Roll
处理程序干净整洁:
滚动->
(模型,Random.generate NewFaces diePairGenerator)
如果您想尝试超越这一点,请考虑需要什么来允许任何数量的模具滚动。采用从更原始的生成器构建复杂生成器的想法,并使用模块us的文档作为指南。一种方法是像这里一样使用批处理 另一种方法是使用
Random.pair
或Random.list
,如果您需要两个以上:
导入Html公开(…)
将Html.App导入为Html
导入Html.Events公开(..)
导入Html.Attributes(..)
随机输入
主:程序永远不会
主要=
Html.program
{init=init
,视图=视图
,update=update
,订阅=订阅
}
--模型
类型别名模型=
{dieFaces:(List Int)
}
-- http://stackoverflow.com/questions/23199398/how-do-i-get-a-list-item-by-index-in-elm#comment56252508_23201661
获取:Int->List a->Maybe a
get n xs=List.head(List.drop n xs)
-- http://rundis.github.io/blog/2016/elm_maybe.html
getOrOne:Int->List Int->Int
getOrOne n xs=Maybe.withDefault 1(get n xs)
初始化:(模型,Cmd Msg)
初始化=
(型号[1,1],命令无)
--更新
输入味精
=滚动
|NewFace(列表Int)
更新:Msg->Model->(Model,Cmd-Msg)
更新msg模型=
味精案例
滚动->
(模型,Random.generate NewFace(Random.list 2(Random.int 1 6)))
新面孔新面孔->
(型号newFace,命令:无)
--订阅
订阅:模型->子消息
订阅模式=
无
--看法
查看:模型->Html消息
视图模型=
分区[]
[img[src(“/img/Alea_”++toString(getOrOne 0 model.dieFaces)+.png”)][]
,img[src(“/img/Alea_”++toString(getOrOne 1 model.dieFaces)++.png”)][]
,按钮[onClick Roll][text“Roll”]
]
另一个除了@ChadGilbert接受的答案中描述的更改外,我还必须更改
新面孔
更新案例(使用elm 0.18.0
)
太棒了,也感谢您提供了指向文档正确部分的指针。我认为,制作n个骰子卷可能需要参数化Random.list of Random.int以包含所需骰子的数量。谢谢你的回答和新作业。谢谢查德的详细解释。工作得很有魅力。我已经为懒人设定了一个要点:如果我们不期望一个
Int
元组,而是两个Int
参数,那么解决方案是什么样子的?也就是说,如果Msg
被OP直觉定义为NewFaces Int
?如果您有消息NewFaces2 Int
,您的更新
处理程序可能如下所示:(model,Random.generate(uncurry NewFaces2)diePairGenerator)
。该函数将接受tuple参数,并将值作为两个参数传递到NewFaces2
。
NewFaces newFaces ->
let
(newFace1, newFace2) = newFaces
in
(Model newFace1 newFace2, Cmd.none)