Tracks
/
Elm
Elm
/
Temario
/
Tipos opacos
Ti

Tipos opacos en Elm

2 ejercicios

Acerca de Tipos opacos

Introducción

Los tipos opacos son una técnica de encapsulación en Elm. Algunas personas también lo llaman ocultamiento de información, u ocultar los detalles de implementación. También se usan comúnmente para forzar la validación, usando el patrón Parse, dont validate. Por ejemplo, podrías tener un tipo opaco EmailAddress, que solo puede contener direcciones de correo electrónico válidas (a diferencia de un String, que puede contener cualquier cosa).

Cómo crear un tipo opaco

Los tipos personalizados tienen una o más variantes, y el compilador genera automáticamente una función para crear cada variante, usando el nombre de la variante. Esta es la única forma en que se pueden crear los tipos personalizados. El compilador también permite la desestructuración de estas variantes.

type Maybe a
    = Nothing --> Variant implies a 'Nothing' function, with type 'Maybe a', and destructuring of 'Nothing'
    | Just a  --> Variant implies a 'Just' function, with type 'a -> Maybe a', and destructuring of 'Just _'

De forma predeterminada, todo esto es interno al archivo o módulo, y usamos la palabra clave exposing para elegir qué exportar. El módulo Maybe expone el tipo Maybe (para que otros módulos puedan usar valores Maybe existentes) y también expone las variantes Nothing y Just (para que otros módulos puedan crear y desestructurar valores Maybe). Usa la siguiente sintaxis para hacerlo. La parte Maybe(..) le dice a Elm que exponga todas las variantes, además de la definición del tipo personalizado.

module Maybe exposing
  ( Maybe(..)
  -- ...
  )

Para crear un tipo opaco, simplemente eliges no exportar las variantes. Para hacerlo con el tipo Maybe, usarías la siguiente sintaxis:

module Maybe exposing
  ( Maybe
  -- ...
  )

Cuando haces esto, casi siempre necesitas proporcionar otra forma de crear y obtener las variantes, exponiendo funciones personalizadas. Estas funciones personalizadas te permiten aplicar cierta lógica al crear y obtener las variantes. Esto oculta los detalles de implementación internos del módulo y significa que puedes cambiar los detalles de implementación tanto como quieras, siempre que las funciones expuestas sigan siendo las mismas. También te permite mantener invariantes al crear y usar el tipo.

Parse, don't validate

Probablemente el uso más común de los tipos opacos sea forzar la validación, usando el patrón Parse, dont validate. En este patrón, expones una función que recibe una entrada con menos estructura o seguridad de tipos de la que quieres, como un String, y luego la conviertes en un tipo más estructurado, como EmailAddress, ya sea devolviendo el tipo o devolviendo un error (normalmente Maybe o Result).

Por ejemplo, en el código de abajo, para los módulos externos solo es posible crear un tipo EmailAddress usando la función parseEmailAddress, así que cuando trabajas con el tipo EmailAddress, tienes la certeza de que es válido.

module EmailAddress exposing ( EmailAddress, parseEmailAddress, getEmailAddress )

-- The `EmailAddress` custom type has one variant, also called `EmailAddress`
-- When a custom type has one variant, it is idiomatic to use the same name for both.
type EmailAddress = 
  EmailAddress String

-- create an EmailAddress variant
parseEmailAddress: String -> Maybe EmailAddress
parseEmailAddress candidateEmailAddress =   
  if isValidEmailAddress candidateEmailAddress then
    Just (EmailAddress candidateEmailAddress)
  else
    Nothing

-- get an EmailAddress variant
getEmailAddress: EmailAddress -> String
getEmailAddress ( EmailAddress  emailAdress ) =
  emailAdress

isValidEmailAddress: String -> bool
-- ... 
Editar en GitHub El enlace se abre en una ventana o pestaña nueva

Aprende Tipos opacos

La práctica está bloqueada

Desbloquea 1 ejercicio más para practicar Tipos opacos