我想要实现的是类型继承.我的意思是我希望能够让函数返回“子类型”,然后返回一个返回“超类型”的函数.让我给你举个例子 假设我有一个主视图组件,它返回一个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 }