Types elm中的类型继承
我试图实现的是类型继承。我的意思是,我想让函数返回“子类型”,然后返回“超级类型”。让我给你举个例子 假设我有一个主视图组件,它返回一个Html消息Types elm中的类型继承,types,elm,Types,Elm,我试图实现的是类型继承。我的意思是,我想让函数返回“子类型”,然后返回“超级类型”。让我给你举个例子 假设我有一个主视图组件,它返回一个Html消息 view: Model -> Html Msg view model = div [class "goal-box"] [ function_a model, function_b model ] 现在我希望function\u a和function\u b能够返回Msg function\u a
view: Model -> Html Msg
view model =
div [class "goal-box"] [
function_a model,
function_b model
]
现在我希望function\u a
和function\u b
能够返回Msg
function\u a:Model->Html-AMsg
function\u b:Model->Html BMsg
我之所以要这样做,是因为我想确保函数_a在它可以生成何种消息方面受到限制,函数_b也是如此,但最终我需要一个使用这两者的统一视图
因此,将味精定义为
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)
的值
其次,您需要在视图中使用functionHtml.map
来更改消息类型,以便当函数a
发送消息AnotherMsg 34
(类型AMsg
)时,该消息将转换为AMsg(AnotherMsg 34)
(类型Msg
)因此,在您的视图中
所有消息的类型都相同
下面是完整的示例代码,下面是ellie示例:
我认为您正在尝试做的,以及您在上一个问题中尝试做的方式,非常有意义,并且是OCaml中称为多态变体的一个特性。不幸的是,Elm不支持它,这可能是因为这种东西有一些微妙的问题,使它不那么吸引人,特别是对于一门针对初学者的语言。@glennsl是的,我想这就是你在我的另一个问题中试图向我解释的。不幸的是,我的措辞是错误的,还有一些其他的错误使我相信继承是正确的。我想编辑这个问题,但它变得太混乱了,所以我决定删除并重新创建。无论如何,马库斯的回答似乎完成了任务,但我当然希望这是一个更直接的。这可能会发生在将来,我们只是在版本0.19毕竟谢谢!这确实感觉有点麻烦,但至少它完成了任务
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
}