Elm Language
Сбор данных: кортежи, записи и словари
Поиск…
Кортеж
Кортежи - это упорядоченные списки значений любого типа.
(True, "Hello!", 42)
Невозможно изменить структуру кортежа или обновить значение.
Кортежи в Elm считаются примитивным типом данных, а это означает, что вам не нужно импортировать какие-либо модули для использования Tuples.
Доступ к значениям
Модуль Basics имеет две вспомогательные функции для доступа к значениям кортежа с длиной двух ( a, b ) без использования сопоставления шаблонов:
fst (True, "Hello!") -- True
snd (True, "Hello!") -- "Hello!"
Значения доступа кортежей большей длины выполняются путем сопоставления шаблонов.
Согласование образцов
Кортежи чрезвычайно полезны в сочетании с сопоставлением с образцом:
toggleFlag: (Sting, Bool) -> (Sting, Bool)
toggleFlag (name, flag) =
(name, not flag)
Замечания по кортежам
Кортежи содержат менее 7 значений comparable типа данных
Словари
Словари реализованы в основной библиотеке Dict .
Словарь, отображающий уникальные ключи для значений. Ключи могут быть любого сопоставимого типа. Сюда входят Int, Float, Time, Char, String и кортежи или списки сопоставимых типов.
Операции вставки, удаления и запроса все время O (log n).
В отличие от Tuples и Records, словари могут изменять свою структуру, другими словами, можно добавлять и удалять ключи.
Можно обновить значение с помощью ключа.
Также можно получить доступ или обновить значение с помощью динамических клавиш.
Доступ к значениям
Вы можете получить значение из Словаря, используя функцию Dict.get .
Тип определения Dict.get :
get : comparable -> Dict comparable v -> Maybe v
Он всегда будет возвращать Maybe v , потому что можно попытаться получить значение несуществующим ключом.
import Dict
initialUsers =
Dict.fromList [ (1, "John"), (2, "Brad") ]
getUserName id =
initialUsers
|> Dict.get id
|> Maybe.withDefault "Anonymous"
getUserName 2 -- "Brad"
getUserName 0 -- "Anonymous"
Обновление значений
Операция обновления в словаре выполняется с помощью Maybe.map , поскольку запрошенный ключ может отсутствовать.
import Dict
initialUsers =
Dict.fromList [ (1, "John"), (2, "Brad") ]
updatedUsers =
Dict.update 1 (Maybe.map (\name -> name ++ " Johnson")) initialUsers
Maybe.withDefault "No user" (Dict.get 1 updatedUsers) -- "John Johnson"
документация
Запись представляет собой набор пар ключ-значение.
greeter =
{ isMorning: True
, greeting: "Good morning!"
}
Невозможно получить доступ к значению несуществующим ключом.
Невозможно динамически модифицировать структуру Record.
Записи позволяют обновлять значения постоянными ключами.
Доступ к значениям
Доступ к значениям невозможен с помощью динамического ключа для предотвращения возможных ошибок во время выполнения:
isMorningKeyName =
"isMorning "
greeter[isMorningKeyName] -- Compiler error
greeter.isMorning -- True
Альтернативный синтаксис для доступа к значению позволяет извлечь значение при прохождении через запись:
greeter
|> .greeting
|> (++) " Have a nice day!" -- "Good morning! Have a nice day!"
Типы расширений
Иногда вам нужна подпись параметра для ограничения типов записей, которые вы передаете в функции. Расширение типов записей делает идею супертипов ненужной. В следующем примере показано, как эта концепция может быть реализована:
type alias Person =
{ name : String
}
type alias Animal =
{ name : String
}
peter : Person
peter =
{ name = "Peter" }
dog : Animal
dog =
{ name = "Dog" }
getName : { a | name : String } -> String
getName livingThing =
livingThing.name
bothNames : String
bothNames =
getName peter ++ " " ++ getName dog
Мы могли бы даже продлить записи дальше и сделать что-то вроде:
type alias Named a = { a | name : String }
type alias Totalled a = { a | total : Int }
totallyNamed : Named ( Totalled { age : Int })
totallyNamed =
{ name = "Peter Pan"
, total = 1337
, age = 14
}
Теперь у нас есть способы передать эти частичные типы в функциях:
changeName : Named a -> String -> Named a
changeName a newName =
{ a | name = newName }
cptHook = changeName totallyNamed "Cpt. Hook" |> Debug.log "who?"
Обновление значений
У Elm есть специальный синтаксис для обновления записей:
model =
{ id: 1
, score: 0
, name: "John Doe"
}
update model =
{ model
| score = model.score + 100
| name = "John Johnson"
}