【发布时间】:2018-07-05 20:34:19
【问题描述】:
我的主程序有一个update函数
update : Msg -> Model -> ( Model, Cmd Msg )
为了与子组件通信,我们可以添加另一个变体并将我们的消息包装在一个新消息中
type alias Model =
{ ...
, child : Child.Model
}
type Msg
= ...
| ChildMsg Child.Msg
update msg model =
case msg of
...
ChildMsg childMsg ->
let
( childModel, cmd ) =
Child.update childMsg model.child
updatedModel =
{ model | child = childModel }
childCmd =
Cmd.map ChildMsg cmd
in
( updatedModel, childCmd )
但是,如果我的子组件的 update 函数的类型与父组件不匹配,这似乎具有挑战性。考虑一个具有多态更新函数的孩子:
-- PolymorphicChild.elm
update : Msg a -> Model -> ( Model, Cmd (Msg a) )
当从这个模块运行命令时,我必须把它包装起来
PolymorphicChild.someCommand : Cmd (Msg Foo)
PolymorphicChild.someCommand
|> Cmd.map PolymorphicChild
但是,这会产生一个Msg (PolymorphicChild.Msg Foo),而不是我的应用所期望的Msg PolymorphicChild.Msg。
The right side of (|>) is causing a type mismatch.
(|>) is expecting the right side to be a:
Cmd (PolyMorphicChild.Msg Foo) -> a
But the right side is:
Cmd Polymorphic.Msg -> Cmd Msg
我尝试将多态参数添加到App.Msg
-- App.elm
type Msg a =
= ..
| PolymorphicChildMsg (PolymorphicChild.Msg a)
但它基本上炸毁了我的整个程序。涉及App.Msg 的每个函数都需要以某种方式进行更改以使用新的子组件。
如何统一这两种类型并使两个组件协同工作?
【问题讨论】:
-
您能否更深入地了解您要完成的工作?孩子的目的是什么?可能有一种不同的方法,而不是在对象图中冒泡一个未确定的类型参数。
-
为 Wordpress 制作 Elm 前端 - 在此过程中遇到了一些有趣的挑战...这里有一个 link 向您展示我在说什么。我不能把所有的都贴在 Ellie 上,因为它只允许一个文件,但我认为它足以得到图片。我考虑过将所有这些都带入主要的
App,但我希望将与 Wordpress 后端相关的内容保留在一个独立的模块中。我是基于类型的编程的新手,所以我可能正在做一些愚蠢的事情...... -
这是最近几个月努力让新手停止思考“组件”的事情之一,而 Elm 并没有真正做到这一点。查看“文件的生命周期”youtube.com/watch?v=XpDsk374LDE 或“缩放 Elm 应用程序”youtube.com/watch?v=DoA4Txr4GUs 以获得更好的理论基础。我仍然一直在制作类似于“子组件”的应用程序,但我尝试尽可能长时间地使用扁平结构,然后在它变得太大并且有太多不相关时重构功能相同的更新功能。
-
@wmakley 感谢分享。实际上,我上周观看了这两个视频,并完全根据我学到的知识重构了这个模块。没有更多的子组件:D
标签: functional-programming polymorphism elm unification union-types