Elm es un lenguaje de tipado estático e inferencia fuerte: el compilador deduce los tipos automáticamente, pero también te permite declarar funciones genéricas que funcionan con más de un tipo.
Por ejemplo:
identity : a -> a
identity x = x
Esta función acepta cualquier tipo a.
Sin embargo, a veces queremos restringir qué tipos son válidos.
Ahí entran en juego los type constraints (restricciones de tipo).
En Elm, los type constraints permiten decir:
> “Este tipo genérico debe cumplir con ciertas propiedades (por ejemplo, ser comparable o numérico)”.
A diferencia de Haskell o Scala, Elm no tiene type classes, pero ofrece un pequeño conjunto de restricciones integradas que cubren los casos más comunes.
Elm define cuatro categorías de tipos con restricciones que podés usar en tus firmas de tipo:
- number: Tipos que soportan operaciones aritméticas como Int, Float
- comparable: Tipos que pueden ordenarse o compararse como Int, Float, Char, String, tuples de comparables
- appendable: Tipos que pueden concatenarse como String, List a
- compappend:| Tipos que son a la vez comparable y appendable
Podés restringir una función a operar solo sobre números:
sumar : number -> number -> number
sumar x y =
x + y
Esto funciona con Int o Float, pero no con String.
Si necesitás ordenar o comparar valores:
menor : comparable -> comparable -> comparable
menor a b =
if a < b then
a
else
b
O incluso:
ordenar : List comparable -> List comparable
ordenar lista =
List.sort lista
Cuando querés concatenar elementos:
concatenar : appendable -> appendable -> appendable
concatenar a b =
a ++ b
Funciona con:
concatenar "Hola, " "mundo!" -- "Hola, mundo!"
concatenar [1,2] [3,4] -- [1,2,3,4]
En Elm no se pueden definir tipos personalizados que sean comparable o appendable.
Por ejemplo, este tipo:
type alias Persona =
{ nombre : String, edad : Int }
No puede usarse en una función List.sort directamente.
Pero podés ordenarlo con una clave usando List.sortBy:
ordenarPorEdad : List Persona -> List Persona
ordenarPorEdad personas =
List.sortBy .edad personas
O definir un criterio personalizado:
ordenarPorNombreDesc : List Persona -> List Persona
ordenarPorNombreDesc personas =
List.sortWith (\a b -> compare b.nombre a.nombre) personas
Elm mantiene su sistema de tipos simple pero poderoso: no hay typeclasses ni herencia, pero sí restricciones útiles y seguras para los casos más comunes.
