In Elm, is there a way to merge union types ? (for modularity purpose)

六月ゝ 毕业季﹏ 提交于 2019-12-04 08:27:35

@z5h's answer is almost correct, but the type constructors have to have different names.

You can't merge the types the way you'd like to.

As for the idiomatic way: You would name the split types just Msg, not Page1Msg. So, for example:

Page1.elm:

module Page1 exposing (Msg)

type Msg
  = Foo

Page2.elm:

module Page2 exposing (Msg)

type Msg
  = Bar

Shared.elm:

module Shared exposing (Msg)

type Msg
  = Baz

Main.elm:

module Main exposing (..)

import Shared
import Page1
import Page2

type Msg
  = SomethingCustom
  | SharedMsg Shared.Msg
  | Page1Msg Page1.Msg
  | Page2Msg Page2.Msg

By the way, remember that if you split the modules into Page1.View, Page1.Types, etc., then as long as the exposed functions don't overlap, you can import different modules under the same name, ie:

import Page1.Types as Page1
import Page1.State as Page1
import Page1.View as Page1
import Page1.Decoders as Page1

Do not forget that you are absolutely not obliged to follow the update-view definitions exactly as in the basic examples. In your case, you could adapt the update function to your needs

how about in parent:

update message model = 
    let 
        sharedMsgs = 
            { msg1 = Msg1 
            , msg2 = Msg2 
            }

    in case message of
        Page1Msg msg ->
            let (m, c) =
                update sharedMsgs msg model.page1
            in case c of 
                Nothing ->
                    m 
                Just c ->
                    update c m

where the update function in page1 has signature

update : SharedMessages msg -> Msg -> Page1Model -> (Page1Model, Maybe msg)

The problem is, you've said:

type SharedMsg
   = SharedAction

So we know the type of SharedAction is a SharedMsg.
But then you say:

type Msg
   = SharedAction
   | Page1Action
   | Page2Action

So now a contradiction, in that SharedAction is a Msg.

The easy way to work around this is to say:

type Msg
   = Msg SharedMsg
   | Msg Page1Msg
   | Msg Page2Msg

I.e. Msg is a constructor who's instances are of type Msg, which can have the following values.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!