我想要实现的是类型继承。我的意思是我希望能够让函数返回“子类型”,然后一个函数返回“父类(super class)型”。让我给你举个例子
假设我有一个主要的 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 在它可以产生的消息类型方面受到限制,function_b 也是如此,但最终我需要一个使用两者的统一 View 。
所以自然而然地将 Msg 定义为
type Msg
= AMsg
| BMsg
type AMsg
= AnotherMsg Int
| AgainMsg Int
type BMsg
= ThisMsg String
| ThatMsg Int
这似乎不起作用,因为编译器告诉我它期望类型为
Html Msg
的返回值而不是 Html AMsg
.我希望这很清楚。我觉得类型是我在 JS 中最挣扎的概念,但希望我正朝着正确的方向前进。
免责声明
当天早些时候我曾问过一个类似的问题,但我意识到我犯了一个错误,然后在编辑它时让自己困惑了几次。所以我不得不删除它。提前向花时间阅读并回答的人道歉。
最佳答案
这里有两个主要问题。
首先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
中所有消息都是相同的类型。下面是完整的示例代码,这里有 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
}
关于types - 榆树中的类型继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53330051/