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
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
}
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
Neste exercício, você vai escrever um TreasureChest genérico (e mágico!), para guardar alguns tesouros.
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.
Essa função deve receber dois parâmetros
String (para tentar uma senha)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.
Essa função (de ordem superior) deve receber dois parâmetros
TreasureChest, também com o mesmo tipo genéricoEssa 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)
Crie sua conta no Exercism para aprender e dominar Elm com 28 conceitos110 exercícios e mentoria humana de verdade, tudo de graça.