Translate

viernes, 8 de agosto de 2025

Tipos personalizados en Elm



Hasta ahora hemos visto varios tipos como Bool, Int y String. Pero ¿cómo definimos los nuestros?

Supongamos que estamos creando una sala de chat. Todos necesitan un nombre, pero algunos usuarios no tienen una cuenta permanente. Simplemente dan un nombre cada vez que acceden.

Podemos describir esta situación definiendo el tipo UserStatus, enumerando todas las posibles variaciones:


type UserStatus = Regular | Visitor


El tipo UserStatus tiene dos variantes: un usuario puede ser Regular o un Visitante. Por lo tanto, podríamos representar a un usuario como un registro de la siguiente manera:


type UserStatus

   = Regular

   | Visitor


type alias User =

{ status : UserStatus

, name : String

}


thomas = { status = Regular, name = "Thomas" }

kate95 = { status = Visitor, name = "kate95" }


Ahora podemos rastrear si un usuario es Regular con cuenta o un Visitante de paso. No es muy complicado, ¡pero podemos simplificarlo!


En lugar de crear un tipo personalizado y un alias, podemos representar todo esto con un solo tipo personalizado. Las variantes Regular y Visitor tienen datos asociados. En nuestro caso, estos datos son un valor de cadena:


type User

   = Regular String

    | Visitor String


thomas = Regular "Thomas"

kate95 = Visitor "kate95"


Los datos se adjuntan directamente a la variante, por lo que ya no es necesario el registro.

Otra ventaja de este enfoque es que cada variante puede tener diferentes datos asociados. Supongamos que los usuarios Regulares proporcionaron su edad al registrarse. No hay una forma sencilla de capturar esto con registros, pero al definir tu propio tipo personalizado, no hay problema. Añadamos algunos datos asociados a la variante Regular :


> type User

   = Regular String Int

   | Visitor String


> Regular

<function> : String -> Int -> User


> Visitor

<function> : String -> User


> Regular "Thomas" 44

Regular "Thomas" 44 : User


> Visitor "kate95"

Visitor "kate95" : User


Solo hemos añadido la edad, pero las variantes de un tipo pueden variar bastante. Por ejemplo, quizá queramos añadir la ubicación de los usuarios Regulares para poder sugerir salas de chat regionales. O quizá queramos tener usuarios anónimos:


type User

  = Regular String Int Location

  | Visitor String

  | Anonymous



martes, 5 de agosto de 2025

Modelado en Elm


Los tipos personalizados se vuelven extremadamente potentes cuando se empiezan a modelar situaciones con mucha precisión. Por ejemplo, si se espera la carga de datos, se podría modelar con un tipo personalizado como este:


type Profile

   = Failure

   | Loading

   | Success { name : String, description : String }


De esta forma, se puede empezar en el estado de carga y luego pasar a Failure o Success según lo que ocurra. Esto simplifica enormemente la creación de una función de vista que siempre muestre algo razonable cuando se cargan los datos.

Los tipos personalizados son la característica más importante de Elm. Ofrecen mucha profundidad, especialmente una vez que se adquiere el hábito de modelar escenarios con mayor precisión. 

¿Qué es un LLM y como empezamos a aprenderlo?


Un Large Language Model (LLM) es un modelo de inteligencia artificial entrenado con enormes volúmenes de texto para entender y generar lenguaje humano. Son la base de tecnologías como ChatGPT, Copilot o traductores automáticos avanzados.

Lo revolucionario de los LLMs es su capacidad para responder preguntas, escribir código, redactar textos, traducir, razonar y aprender patrones del lenguaje con una fluidez que antes parecía imposible.

Los LLMs no son solo una moda: están transformando la manera en que interactuamos con la información, automatizamos tareas y diseñamos productos inteligentes.


Y ¿Por dónde empezar? Libros para aprender sobre LLMs:

  • "Deep Learning" – Ian Goodfellow, Yoshua Bengio, Aaron Courville (Clásico, incluye fundamentos clave para entender redes profundas)
  • "Natural Language Processing with Transformers" – Lewis Tunstall, Leandro von Werra, Thomas Wolf (Excelente para entender cómo funcionan los LLMs modernos, como los de Hugging Face)
  • "Transformers for Natural Language Processing" – Denis Rothman  (Explica en detalle el modelo Transformer y cómo se aplica en NLP)
  • "The Hundred-Page Machine Learning Book" – Andriy Burkov  (Rápido, claro, cubre muchos fundamentos útiles para entender modelos como los LLMs)



Mensajes en Elm


En este post vimos un par de ejemplos de definición de un tipo Msg. Este tipo de tipo es muy común en Elm. En nuestra sala de chat, podríamos definir un tipo Msg de la siguiente manera:


type Msg

    = PressedEnter

    | ChangedDraft String

    | ReceivedMessage {user: User, message: String}

    | ClickedExit


Tenemos cuatro variantes. Algunas no tienen datos asociados, otras sí. Observe que ReceivedMessage tiene un registro como dato asociado. Esto es perfectamente correcto. ¡Cualquier tipo puede ser un dato asociado! Esto le permite describir las interacciones en su aplicación con mucha precisión.


Constructores de Registros en Elm


Al crear un alias de tipo específico para un registro, también se genera un constructor de registros. Por lo tanto, si definimos un alias de tipo Usuario, podemos empezar a construir registros de la siguiente manera:


> type alias Usuario = { nombre: String, edad: Int}


> Usuario

<función>: String -> Int -> Usuario


> Usuario "Sue" 58

{ nombre = "Sue", edad = 58}: Usuario


> Usuario "Tom" 31

{ nombre = "Tom", edad = 31}: Usuario


Ten en cuenta que el orden de los argumentos en el constructor de registros coincide con el orden de los campos en el alias de tipo.


Reiteramos que esto es solo para registros. Crear alias de tipo para otros tipos no generará un constructor.

viernes, 1 de agosto de 2025

Modelos en Elm


Es muy común usar alias de tipo al diseñar un modelo. Cuando estábamos aprendiendo sobre la arquitectura de Elm, vimos un modelo como este:


type alias Model =

  { name : String

  , password : String

  , passwordAgain : String

  }


La principal ventaja de usar un alias de tipo para esto es que al escribir las anotaciones de tipo para las funciones de actualización y vista, es mucho más fácil escribir Msg -> Modelo -> Modelo que la versión completa. Además, permite añadir campos a nuestro modelo sin necesidad de modificar ninguna anotación de tipo.