Trilhas
/
Elm
Elm
/
Exercícios
/
Baú de Tesouro
Baú de Tesouro

Baú de Tesouro

Exercício de aprendizagem

Introdução

Genéricos

Introdução

Genéricos são um recurso da linguagem que permite reutilizar código. Por exemplo, não deveria importar qual tipo uma lista contém para calcular o seu comprimento. É por isso que a função length usa um parâmetro de tipo genérico a na sua assinatura de tipo.

length : List a -> Int

Parâmetros em tipos

Quando um tipo é genérico sobre outro tipo, usamos um nome em minúsculas para esse outro tipo e o chamamos de parâmetro de tipo. Exemplos comuns são os tipos personalizados List, Maybe e Result.

-- Maybe is generic over the type a
type Maybe a
    = Nothing
    | Just a

someString : Maybe String
someString = Just "hello"

someInt : Maybe Int
someInt = Just 42

Uma observação importante sobre os nomes dos parâmetros de tipo é que eles podem ter vários caracteres. A única restrição é que devem ser nomes em minúsculas. Por isso, quando é útil, costumamos dar a eles nomes descritivos.

Um tipo pode ser genérico sobre vários outros tipos e, portanto, ter vários parâmetros de tipo. Nesse caso, cada tipo independente recebe um nome diferente em minúsculas. Serem independentes não impede que se tornem o mesmo tipo, apenas permite que sejam diferentes.

-- Result is generic over the types error and value
type Result error value
    = Ok value
    | Err error

Aliases de tipo de registro também podem ter parâmetros de tipo, embora seja menos comum.

-- Event is generic over the type a
type alias Event a =
    { at : Time
    , data : a 
    }

Parâmetros de tipo em funções

Como os tipos podem ser genéricos, as funções também podem. Funções que lidam com tipos genéricos podem ser escritas, como a Maybe.withDefault.

withDefault : a -> Maybe a -> a
withDefault default maybe =
    case maybe of
      Just value -> value
      Nothing -> default

Funções que recebem outras funções como parâmetros são chamadas de funções de ordem superior, e elas também podem ser genéricas.

map : (a -> b) -> Maybe a -> Maybe b
map function maybe =
  case maybe of
    Just value ->
      Just (function value)

    Nothing ->
      Nothing

Instruções

Neste exercício, você vai escrever um TreasureChest genérico (e mágico!), para guardar alguns tesouros.

1. Defina o tipo customizado genérico TreasureChest

Defina um tipo customizado TreasureChest com uma única variante.

A variante deve ter um valor String associado, que será usado para armazenar a senha do baú do tesouro.

A variante também deve ter um valor genérico associado, que será usado para armazenar o tesouro. Esse valor é genérico para que o tesouro possa ser qualquer coisa.

2. Defina a função getTreasure

Essa função deve receber dois parâmetros

  • uma String (para tentar uma senha)
  • um tipo customizado genérico TreasureChest

Essa função deve comparar a tentativa de senha fornecida com a String no TreasureChest.

A função deve retornar um Maybe.

Se as senhas coincidirem, retorne Just com o valor genérico do TreasureChest (o tesouro!)

Se as senhas não coincidirem, retorne Nothing.

3. Defina a função multiplyTreasure

Essa função (de ordem superior) deve receber dois parâmetros

  • uma função multiplicadora que recebe um parâmetro genérico e retorna uma lista do mesmo tipo genérico
  • um tipo customizado genérico TreasureChest, também com o mesmo tipo genérico

Essa função deve chamar a função multiplicadora com o tesouro no baú.

A função deve retornar um novo TreasureChest, com a mesma senha do original e com o tesouro multiplicado (o retorno)

Editar via GitHub O link abre em uma nova janela ou aba
Elm Exercism

Tudo pronto para começar Baú de Tesouro?

Crie sua conta no Exercism para aprender e dominar Elm com 28 conceitos110 exercícios e mentoria humana de verdade, tudo de graça.