2016-02-24 3 views
3

Я читаю http://elm-lang.org/guide/model-the-problem и хочу лучше понимать Tagged Unions in Elm. В частности, я наткнулся на этот пример:Tagged Unions in Elm

type Scale = Normal | Logarithmic 
type Widget 
    = ScatterPlot (List (Int, Int)) 
    | LogData (List String) 
    | TimePlot Scale (List (Time, Int)) 

Я так думаю, что это интерпретируется следующим образом:

  1. Scale тип 2 возможных значений: Normal или Logarithmic
  2. Widget тип с 3 возможных значения: ScatterPlot, LogData, или

Однако, как мне интерпретировать (List (Int, Int)) часть в ScatterPlot? Аналогично, как мне интерпретировать часть Scale (List (Time, Int)) в TimePlot?

ответ

3

List является встроенным типом, принимая один параметр (другой тип) и означает « список, содержащий значения этого типа в качестве его элементов ». Таким образом, List (Int, Int) - это список (Int, Int). Итак, что такое (Int, Int)?

В целом любой (a, b) является кортежем с элементами типа a и типа b. Кортеж немного похож на запись без имен полей, поэтому вы можете различать только элементы по их положению, однако в отличие от списка элементы могут быть разных типов. Итак, (Int, Int) - это кортеж, содержащий два Int s, где Int - всего лишь целое число.

Таким образом, List (Int, Int) - это список кортежей из двух целых чисел.

С TimePlot у вас фактически есть два разных типа параметров - Scale и List (Time, Int). Последнее должно теперь иметь смысл с учетом объяснения List (Int, Int) - только кортеж имеет Time в качестве своего первого типа вместо Int.

Таким образом, TimePlot принимает два типа параметров, и он становится TimePlot Scale (List (Time, Int)).

В Elm и родственных языках, тип обозначение (и прикладная функция) определены таким образом, что любое выражение a b c d означает a с параметрами b, c и d. Если c d предназначен для одного параметра, он помещается в круглые скобки.

Как говорит Андреас, подумайте о тегах союза как о функциях - они действительно есть, на самом деле их называют «конструкторами типов». TimePlot - это функция, принимающая Scale и List (Time, Int) и возвращающая Widget. Normal - это функция без параметров, которая возвращает Scale и так далее.

+0

Благодарим вас за подробное объяснение - это имеет смысл! Я думаю, что часть путаницы, с которой я столкнулся, заключалась в том, как используются круглые скобки, но ваше объяснение прояснило это! – wmock

+0

другой связанный вопрос, но как бы вы интерпретировали аннотацию этого типа: 'String.toInt: String -> Результат String Int'? То, как я понимаю это, заключается в том, что функция toInt принимает 'String' как входную и возвращает значение типа' Result String Int', правильно? Однако, как выглядит правильное значение 'Result String Int'? – wmock

+1

«Значение ошибки результата» - это тип, который указывает на результат операции. В этом случае 'error' является' String' и 'value' является' Int', поэтому, если операция не увенчалась успехом, вы получите 'String' - возможно, сообщение об ошибке - и если вы это делаете, вы получите' Int' , Это дискриминационный тип объединения, поэтому вы можете сопоставить шаблон с ним - ветка успеха - 'Ok', а ветвь ошибки -' Err'. См. Http://package.elm-lang.org/packages/elm-lang/core/3.0.0/Result –

1

Просто подумайте о них как о функциях подписи. Таким образом, разброс точек должен быть создан как этот

ScatterPlot [(1,1), (2,2)] 

и когда вы шаблон матч это в case заявлении

case widget of 
    ScatterPlot l -> l -- l is from type (List (Int, Int)) 
    LogData l -> l -- l is from type (List String) 
    TimePlot l -> l -- l is from type Scale (List (Time, Int))