Elm:使用 "type" 属性 为 JSON 输入别名

Elm: Type alias for JSON with "type" property

我有一些 JSON 和 "type" 属性 我想导入 Elm。例如,{ "id": "abc", "type": "thing" } 但是,如果我将带有 type 的类型别名定义为 属性,编译器会报错。例如,

type alias Foo = {
      id: String
    , type: String
}

生产

It looks like the keyword `type` is being used as a variable.

3│     , type: String
              ^
Rename it to something else.

认真的?我必须重命名 属性?有没有办法引用或转义它以便编译?

无路可逃。榆树不妥协。

是的,type是保留关键字,不能用作记录中的字段名。

在 Elm 和 Haskell 中,在你的情况下最常见的事情似乎是附加一个单引号,所以它变成 type',你的类型定义变成

type alias Foo =
  { id: String
  , type': String
  }

这起源于数学prime symbol。乍一看可能很奇怪,但它是有效的语法。

然后您可以使用以下 Json 解码器将 JSON 翻译成 Foo:

fooDecoder =
  Json.object2
    Foo
    ("id" := Json.string)
    ("type" := Json.string)

请注意,Elm 中的确切字段名称不需要与 JSON 字段名称匹配。

您很少会找到一种语言可以让您使用关键字作为未转义的变量名。此行为并非 Elm 独有。

在 oscpad 中,我通过 websockets 在 json 界面中使用 "type" 字段。但是我在榆树记录中没有一个名为 type 的字段。我只是在解析 JSON 时查找 "type" 字段。我的代码如下所示:

jsSpec : JD.Decoder Spec
jsSpec =
  ("type" := JD.string) `JD.andThen` jsCs

jsCs : String -> JD.Decoder Spec
jsCs t =
  case t of
    "button" -> SvgButton.jsSpec `JD.andThen` (\a -> JD.succeed (CsButton a))
    "slider" -> SvgSlider.jsSpec `JD.andThen` (\a -> JD.succeed (CsSlider a))
    "label" -> SvgLabel.jsSpec `JD.andThen` (\a -> JD.succeed (CsLabel a))
    "sizer" -> jsSzSpec `JD.andThen` (\a -> JD.succeed (CsSizer a))
    _ -> JD.fail ("unkown type: " ++ t)

您现在可以使用下划线转义关键字。

例如

type alias Foo =
  { id: String
  , type_: String
}