在elm中键入继承

Nic*_*tti 4 types elm

我想要实现的是类型继承.我的意思是我希望能够让函数返回"子类型",然后返回一个返回"超类型"的函数.让我给你举个例子

假设我有一个主视图组件,它返回一个Html消息

view:  Model -> Html Msg
view model = 
    div [class "goal-box"] [
      function_a model,
      function_b model
    ]
Run Code Online (Sandbox Code Playgroud)

现在我想function_afunction_b每个人都能够返回一个子类型Msg

function_a: Model -> Html AMsg

function_b: Model -> Html BMsg

我想要这个的原因是因为我想确保function_a受限于它可以产生什么样的Msg,同样适用于function_b,但最终我需要一个使用两者的统一视图.

所以很自然的是将Msg定义为

type Msg 
  = AMsg
  | BMsg

type AMsg
  = AnotherMsg Int
  | AgainMsg Int

type BMsg
  = ThisMsg String
  | ThatMsg Int
Run Code Online (Sandbox Code Playgroud)

这似乎不起作用,因为编译器告诉我它期望返回值类型Html Msg而不是Html AMsg.

我希望这很清楚.我觉得类型是我正在努力争取最多来自JS的概念,但希望我朝着正确的方向前进.

免责声明

我在当天早些时候问了一个类似的问题,但我意识到我犯了一个错误,然后在我编辑它时混淆了几次.所以我不得不删除它.向花时间阅读和回答的人们道歉.

Mar*_*ire 6

这里有两个主要问题.

首先AMsg,BMsg在您Msg不参考这些类型的情况下,它们只是您的Msg类型的构造函数.

您需要将其更改为:

type Msg 
  = AMsg AMsg
  | BMsg BMsg
Run Code Online (Sandbox Code Playgroud)

这里第一行AMsg和第一BMsg行是Msg类型的构造函数,第二行是指其他类型.在此之后,你可以创建像这样的值AMsg (AnotherMsg 34).

其次,你需要使用的功能Html.mapview改变消息类型,这样,当如function_a发送消息AnotherMsg 34(类型的AMsg),将被改造成AMsg (AnotherMsg 34)(类型Msg,并在你的),所以view所有的消息都是同一类型的.

以下是完整的示例代码,其中有ellie示例:https://ellie-app.com/3TG62zDLvwFa1

module Main exposing (main)

import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)

type alias Model =
    {}

init : Model
init =
    {}

type Msg 
  = AMsg AMsg
  | BMsg BMsg

type AMsg
  = AnotherMsg Int
  | AgainMsg Int

type BMsg
  = ThisMsg String
  | ThatMsg Int

view : Model -> Html Msg
view model = 
    div [] [
      Html.map AMsg (function_a model),
      Html.map BMsg (function_b model)
    ]

function_a : Model -> Html AMsg
function_a model =
    div [] [ text "A" ]

function_b : Model -> Html BMsg
function_b model =
    div [] [ text "B" ]

update : Msg -> Model -> Model
update msg model =
    model

main : Program () Model Msg
main =
    Browser.sandbox
        { init = init
        , view = view
        , update = update
        }
Run Code Online (Sandbox Code Playgroud)