Как узнать тип данных значения типа суммы [duplicate]

Это довольно читаемо и отлично работает:

var ref = Firebase(url:MY_FIREBASE_URL)
ref.childByAppendingPath("some-child").observeSingleEventOfType(
  FEventType.Value, withBlock: { (snapshot) -> Void in

      for child in snapshot.children {

        let childSnapshot = snapshot.childSnapshotForPath(child.key)
        let someValue = childSnapshot.value["key"] as! String
      }
})
34
задан Gaelan 26 March 2014 в 03:27
поделиться

5 ответов

В двух словах, шаблоны похожи на определение кусочных функций в математике. Вы можете указать разные тела функций для разных аргументов, используя шаблоны. Когда вы вызываете функцию, соответствующий орган выбирается путем сравнения фактических аргументов с различными шаблонами аргументов. Прочтите Нежное введение в Haskell для получения дополнительной информации.

Сравнить:

Fibonacci sequence [/g2]

с эквивалентом Haskell:

fib 0 = 1
fib 1 = 1
fib n | n >= 2 
      = fib (n-1) + fib (n-2)

Обратите внимание, что « n ≥ 2» в кусочной функции становится защитой в версии Haskell, но два других условия являются просто шаблонами. Шаблоны - это условия, которые проверяют значения и структуру, такие как x:xs, (x, y, z) или Just x. В кусочном определении условия, основанные на = или отношениях (в основном, условия, которые говорят что-то », являются« чем-то другим), становятся образцами. Охранники допускают более общие условия. Мы могли бы переписать fib для использования охранников:

fib n | n == 0 = 1
      | n == 1 = 1
      | n >= 2 = fib (n-1) + fib (n-2)
56
ответ дан outis 27 August 2018 в 10:02
поделиться

Совпадение шаблонов, по крайней мере, в Haskell, глубоко связано с понятием алгебраических типов данных . Когда вы объявляете тип данных следующим образом:

data SomeData = Foo Int Int
              | Bar String
              | Baz

... он определяет Foo, Bar и Baz как конструкторы - не должен быть путают с «конструкторами» в ООП, которые строят значение SomeData из других значений.

Совпадение шаблонов не более чем делает это в обратном порядке - шаблон «деконструировать» значение SomeData в его составные части (на самом деле, я считаю, что сопоставление с образцом является способом only для извлечения значений в Haskell).

Когда есть несколько конструкторы для типа, вы пишете несколько версий функции для каждого шаблона, причем правильный выбирается в зависимости от того, какой конструктор использовался (при условии, что вы написали шаблоны в соответствии со всеми возможными конструкциями, что обычно является хорошей практикой) .

12
ответ дан C. A. McCann 27 August 2018 в 10:02
поделиться

В функциональном языке сопоставление шаблонов включает проверку аргумента в отношении разных форм. Простой пример включает рекурсивно определенные операции над списками. Я буду использовать OCaml для объяснения соответствия шаблонов, так как это мой функциональный язык выбора, но понятия в F # и Haskell, AFAIK. - [1] Вот определение функции для вычисления длины списка lst. В OCaml «список is defined recursively as the empty list [] , or the structure h :: t , where h is an element of type a ( a being any type we want, such as an integer or even another list), t is a list (hence the recursive definition), and ::` - это оператор cons, который создает новый список из элемента и списка.

Таким образом, функция будет выглядеть так:

let rec len lst =
  match lst with
    [] -> 0
  | h :: t -> 1 + len t

rec является модификатором, который сообщает OCaml, что функция будет называть себя рекурсивно. Не беспокойтесь об этой части. Утверждение match - это то, на чем мы фокусируемся. OCaml проверит lst на два шаблона - пустой список или h :: t - и вернет другое значение, основанное на этом. Поскольку мы знаем, что каждый список будет соответствовать одному из этих шаблонов, мы можем быть уверены, что наша функция вернется безопасно.

Обратите внимание, что хотя эти два шаблона будут заботиться обо всех списках, вы не ограничены их. [31]

Конечно, использование шаблонов не ограничивается рекурсивно определенными структурами данных или рекурсивными функциями. Вот (надуманная) функция, чтобы рассказать вам, является ли число 1 или 2:

let is_one_or_two num =
  match num with
    1 -> true
  | 2 -> true
  | _ -> false

. В этом случае формы нашего шаблона являются самими числами. _ является специальным catch-all, используемым как случай по умолчанию, если ни один из указанных выше шаблонов не соответствует.

3
ответ дан danben 27 August 2018 в 10:02
поделиться

Совпадение шаблонов - одна из тех болезненных операций, которые трудно обойти, если вы исходите из процедурного программирования. Мне трудно попасть, потому что для сопоставления может использоваться тот же синтаксис, который используется для создания структуры данных.

В F # вы можете использовать оператор cons ::, чтобы добавить элемент в начало list like so:

let a = 1 :: [2;3]
//val a : int list = [1; 2; 3]

Аналогичным образом вы можете использовать один и тот же оператор, чтобы разбить список так:

let a = [1;2;3];;
match a with
    | [a;b] -> printfn "List contains 2 elements" //will match a list with 2 elements
    | a::tail -> printfn "Head is %d" a //will match a list with 2 or more elements
    | [] -> printfn "List is empty" //will match an empty list
1
ответ дан Igor Zevaka 27 August 2018 в 10:02
поделиться

Есть и другие хорошие ответы, поэтому я дам вам очень технический ответ. Соответствие шаблонов - это конструкция исключения для алгебраических типов данных :

  • «Конструкция исключения» означает «как потреблять или использовать значение»
  • «Алгебраический тип данных», в дополнение к первоклассным функциям, является большой идеей в статически типизированном функциональном языке, таком как Clean, F #, Haskell или ML

Идея алгебраических типов данных заключается в том, что вы определяете тип вещи, и вы говорите все способы, которыми вы можете это сделать. В качестве примера давайте определим «Последовательность String» как тип алгебраических данных с тремя способами:

data StringSeq = Empty                    -- the empty sequence
               | Cat StringSeq StringSeq  -- two sequences in succession
               | Single String            -- a sequence holding a single element

Теперь, с этим определением есть все, что не так, но как Например, это интересно, потому что оно обеспечивает конкатенацию последовательностей произвольной длины в постоянное время. (Есть и другие способы достижения этого.) В декларации представлены Empty, Cat и Single, все из которых существуют , создающие последовательности . (Это делает каждый из них введение construct & mdash; способ сделать вещи.)

  • Вы можете сделать пустую последовательность без каких-либо других значений.
  • Чтобы сделать последовательность с Cat, вам понадобятся две другие последовательности.
  • Чтобы сделать последовательность с Single, вам нужен элемент (в этом случае строка)

Здесь идет строка перфорации: конструкция исключения, сопоставление шаблонов, дает вам способ тщательно изучить последовательность и задать вопрос о том, какой конструктор вы создали? Поскольку вы должны быть готовы к любому ответу, вы предоставляете по крайней мере одну альтернативу для каждого конструктора. Вот функция длины:

slen :: StringSeq -> Int
slen s = case s of Empty -> 0
                   Cat s s' -> slen s + slen s'
                   Single _ -> 1

В основе языка все шаблонные сопоставления построены на этой конструкции case. Однако, поскольку алгебраические типы данных и сопоставление образцов настолько важны для идиом языка, существует специальный «синтаксический сахар» для выполнения сопоставления шаблонов в форме объявления определения функции:

slen Empty = 0
slen (Cat s s') = slen s + slen s'
slen (Single _) = 1

С помощью этого синтаксический сахар, вычисление путем сопоставления шаблонов во многом напоминает определение уравнениями. (Комитет Haskell сделал это специально.) И, как вы можете видеть в других ответах, можно выделить либо уравнение, либо альтернативу в выражении case, похлопывая охрану с ним. Я не могу придумать правдоподобного стража для примера последовательности, и в других ответах есть много примеров, поэтому я оставлю его там.

24
ответ дан Norman Ramsey 27 August 2018 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: