当前位置 : 主页 > 手机开发 > 其它 >

types – 在elm中键入继承

来源:互联网 收集:自由互联 发布时间:2021-06-19
我想要实现的是类型继承.我的意思是我希望能够让函数返回“子类型”,然后返回一个返回“超类型”的函数.让我给你举个例子 假设我有一个主视图组件,它返回一个Html消息 view: Model
我想要实现的是类型继承.我的意思是我希望能够让函数返回“子类型”,然后返回一个返回“超类型”的函数.让我给你举个例子

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

view:  Model -> Html Msg
view model = 
    div [class "goal-box"] [
      function_a model,
      function_b model
    ]

现在我希望function_a和function_b能够返回一个Msg的子类型

function_a:模型 – > 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

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

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

免责声明

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

这里有两个主要问题.

首先,Msg中的AMsg和BMsg不引用这些类型,它们只是Msg类型的构造函数.

您需要将其更改为:

type Msg 
  = AMsg AMsg
  | BMsg BMsg

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

其次,您需要在视图中使用函数Html.map来更改消息类型,以便在例如function_a发送消息AnotherMsg 34(类型为AMsg),它将被转换为AMsg(AnotherMsg 34)(类型为Msg),因此在您的视图中所有消息都是相同类型的.

下面是完整的示例代码,这里有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
        }
网友评论