如何读取Elm中的类型定义

slo*_*mbo 1 syntax types elm

我该如何阅读如下的类型定义?

type Config data msg =
  Config
    { toId : data -> String
    , toMsg : State -> msg
    , columns : List (ColumnData data msg)
    , customizations : Customizations data msg
    }
Run Code Online (Sandbox Code Playgroud)

似乎有一个"重复"元素:配置存在于LHS和RHS上.

另一个例子是:

type State =
  State String Bool
Run Code Online (Sandbox Code Playgroud)

这些类型的声明通信是什么?

Jan*_*nar 6

左侧命名您要创建的类型.在右侧,您将定义类型实际可以采用的值.可能只有一个或多少你想要的.

type MyType = ValueA | ValueB | ValueC
Run Code Online (Sandbox Code Playgroud)

此外,您可以创建其值包含额外数据的类型.这可以通过遵循另一种类型的值名称(在形式上称为数据构造函数或Elm中的变体)来完成.您可以使用任何具体类型并具有任意数量.变体之间的类型和arities(参数数量)不需要相同.

type MyType = ValueA String | ValueB Int (List String) | ValueC
Run Code Online (Sandbox Code Playgroud)

这些都是具体类型.当你有一个值时,它将始终具有一个具体的类型.假设您要创建自己的对类型.你可以定义

type PairOfIntAndInt = PairOfIntAndInt Int Int
type PairOfIntAndString = PairOfIntAndString Int String
type PairOfStringAndString = PairOfStringAndString String String
…
Run Code Online (Sandbox Code Playgroud)

但这不会很方便.因此,Elm允许您使用参数获得类型构造函数(即LHS上类型名称的正式名称).它们将以小写字母书写:

type Pair first second = Pair first second
Run Code Online (Sandbox Code Playgroud)

许多有用的核心功能,例如MaybeResult实际上是接受参数的类型.它们也被称为抽象类型.要使它们成为具体类型,您需要将具体类型[^ 1]传递给每个参数.

现在,让我们看看你的代码.你有一个带有Config两个参数的类型构造函数.

type Config data msg =
Run Code Online (Sandbox Code Playgroud)

并且该类型接受使用其一个数据构造函数创建的值

  Config
Run Code Online (Sandbox Code Playgroud)

它存储单个值.值的类型实际上是组合类型,记录.它期望四个字段及其类型将取决于类型构造函数的参数.

    { toId : data -> String
    , toMsg : State -> msg
    , columns : List (ColumnData data msg)
    , customizations : Customizations data msg
    }
Run Code Online (Sandbox Code Playgroud)

例如,如果您有一个具体的类型Config String Int,它将期望以下值:

Config
  { toId = someToIdValue
  , toMsg = someToMsgValue
  , columns = someColumnsValue
  , customizations = someCustomizationsValue
}
Run Code Online (Sandbox Code Playgroud)

其中,someToIdValue将必须的功能回吐String并返回String,toMsg功能从StateInt,等等.

有关详细信息,请参阅https://guide.elm-lang.org/types/custom_types.html

[^ 1]:像Haskell这样的语言实际上允许更狂野的类型.https://wiki.haskell.org/Kind