Тип наследования у вяза - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь достичь наследования типов.Под этим я подразумеваю, что хочу иметь функции, возвращающие «подтипы», а затем функцию, возвращающую «супертип».Позвольте мне привести пример

Допустим, у меня есть основной компонент View, который возвращает Html Msg

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

Теперь я бы хотел, чтобы каждый из function_a и function_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

Это непохоже, работает, так как компилятор говорит мне, что он ожидал возвращаемого значения типа Html Msg, а не Html AMsg.

Надеюсь, это понятно.Я чувствую, что шрифты - это та концепция, с которой я больше всего борюсь с JS, но, надеюсь, я иду в правильном направлении.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ

Я спросиланалогичный вопрос ранее в тот же день, но я понял, что допустил ошибку, а затем несколько раз запутался, редактируя ее.Поэтому мне пришлось удалить его.Заранее извиняюсь перед людьми, которые нашли время, чтобы прочитать его и ответить.

1 Ответ

0 голосов
/ 16 ноября 2018

Здесь есть две основные проблемы.

Во-первых, AMsg и BMsg в вашем Msg не относятся к этим типам, они просто конструкторы для вашего Msg типа.

Вам необходимо изменить это на:

type Msg 
  = AMsg AMsg
  | BMsg BMsg

Здесь первые AMsg и BMsg в каждой строке являются конструкторами для типа Msg, а вторые относятся к другим вашим типам.После этого вы можете создавать значения, такие как AMsg (AnotherMsg 34).

Во-вторых, вам нужно использовать функцию Html.map в вашем view для изменения типов сообщений, чтобы, например, function_a отправлять сообщение AnotherMsg 34 (типаAMsg), который будет преобразован в AMsg (AnotherMsg 34) (типа Msg), и поэтому в вашем view все сообщения имеют одинаковый тип.

Полный пример кода ниже, с примером Элли здесь: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
        }
...