Elm Language
Recopilación de datos: tuplas, registros y diccionarios
Buscar..
Tuplas
Las tuplas son listas ordenadas de valores de cualquier tipo.
(True, "Hello!", 42)
Es imposible cambiar la estructura de un Tuple o actualizar el valor.
Las tuplas en Elm se consideran un tipo de datos primitivo, lo que significa que no es necesario importar ningún módulo para usar tuplas.
Valores de acceso
El módulo básico tiene dos funciones auxiliares para acceder a los valores de una tupla con una longitud de dos ( a, b ) sin utilizar la coincidencia de patrones:
fst (True, "Hello!") -- True
snd (True, "Hello!") -- "Hello!"
Los valores de acceso de las tuplas con una mayor longitud se realizan mediante la coincidencia de patrones.
La coincidencia de patrones
Las tuplas son extremadamente útiles en combinación con la coincidencia de patrones:
toggleFlag: (Sting, Bool) -> (Sting, Bool)
toggleFlag (name, flag) =
(name, not flag)
Observaciones sobre las tuplas
Las tuplas contienen menos de 7 valores de tipo de datos comparable
Los diccionarios
Los diccionarios se implementan en una biblioteca principal de Dict .
Un diccionario mapeando claves únicas a los valores. Las claves pueden ser de cualquier tipo comparable. Esto incluye Int, Float, Time, Char, String y tuplas o listas de tipos comparables.
Las operaciones de inserción, eliminación y consulta llevan tiempo O (log n).
A diferencia de las tuplas y los registros, los diccionarios pueden cambiar su estructura, en otras palabras, es posible agregar y eliminar claves.
Es posible actualizar un valor por una clave.
También es posible acceder o actualizar un valor utilizando teclas dinámicas.
Valores de acceso
Puede recuperar un valor de un Diccionario utilizando una función Dict.get .
Escriba la definición de Dict.get :
get : comparable -> Dict comparable v -> Maybe v
Siempre devolverá Maybe v , porque es posible intentar obtener un valor con una clave que no existe.
import Dict
initialUsers =
Dict.fromList [ (1, "John"), (2, "Brad") ]
getUserName id =
initialUsers
|> Dict.get id
|> Maybe.withDefault "Anonymous"
getUserName 2 -- "Brad"
getUserName 0 -- "Anonymous"
Actualizando valores
La operación de actualización en un Diccionario se realiza utilizando Maybe.map , ya que la clave solicitada puede estar ausente.
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"
Archivos
Registro es un conjunto de pares clave-valor.
greeter =
{ isMorning: True
, greeting: "Good morning!"
}
Es imposible acceder a un valor por una clave inexistente.
Es imposible modificar dinámicamente la estructura del Registro.
Los registros solo le permiten actualizar valores mediante claves constantes.
Valores de acceso
No se puede acceder a los valores con una clave dinámica para evitar posibles errores en el tiempo de ejecución:
isMorningKeyName =
"isMorning "
greeter[isMorningKeyName] -- Compiler error
greeter.isMorning -- True
La sintaxis alternativa para acceder al valor le permite extraer el valor, mientras avanza a través del Registro:
greeter
|> .greeting
|> (++) " Have a nice day!" -- "Good morning! Have a nice day!"
Tipos de extensión
A veces, desearía que la firma de un parámetro restringiera los tipos de registro que pasa a las funciones. Extender los tipos de registro hace que la idea de supertipos no sea necesaria. El siguiente ejemplo muestra cómo se puede implementar este concepto:
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
Incluso podríamos llevar los registros extendidos un paso más allá y hacer algo como:
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
}
Ahora tenemos formas de pasar estos tipos parciales en funciones:
changeName : Named a -> String -> Named a
changeName a newName =
{ a | name = newName }
cptHook = changeName totallyNamed "Cpt. Hook" |> Debug.log "who?"
Actualizando valores
Elm tiene una sintaxis especial para las actualizaciones de registros:
model =
{ id: 1
, score: 0
, name: "John Doe"
}
update model =
{ model
| score = model.score + 100
| name = "John Johnson"
}