特殊类型变量

Elm 定义了以下对编译器具有特定含义的特殊类型变量:

  • comparable :由 IntFloatCharString 和其元组组成。这允许使用 <> 运算符。

    示例: 你可以定义一个函数来查找列表中的最小和最大元素(extent)。你认为要写什么类型的签名。一方面,你可以为 FloatString 写下 extentInt : List Int -> Maybe (Int, Int)extentChar : List Char -> Maybe (Char, Char)。这些的实施将是相同的:

    extentInt list =
      let
        helper x (minimum, maximum) = 
          ((min minimum x), (max maximum x))
      in 
        case list of 
          [] ->
            Nothing
          x::xs ->
            Just <| List.foldr helper (x, x) xs
    

    你可能只想简单地编写 extent : List a -> Maybe (a, a),但编译器不允许你这样做,因为函数 minmax 没有为这些类型定义(注意:这些只是围绕上面提到的 < 运算符的简单包装器)。你可以通过定义 extent : List comparable -> Maybe (comparable, comparable) 来解决这个问题。这允许你的解决方案是多态的,这意味着它将适用于多种类型。

  • number :由 IntFloat 组成。允许使用除除法之外的算术运算符。然后,你可以定义例如 sum : List number -> number 并使其适用于整数和浮点数。

  • appendable :由 StringList 组成。允许使用++运算符。

  • compappend :这有时会出现,但是是编译器的实现细节。目前,这不能在你自己的程序中使用,但有时会提到。

请注意,在这样的类型注释中:number -> number -> number 这些都引用相同的类型,因此传入 Int -> Float -> Int 将是类型错误。你可以通过在类型变量名称中添加一个后缀来解决这个问题:number -> number' -> number''然后编译就好了。

这些没有官方名称,有时也称为:

  • 特殊类型变量
  • 类类型类型变量
  • 伪类型类

这是因为它们像 Haskell 的类型类一样工作,但没有用户定义这些的能力。