Um registo é uma coleção de campos (que podem ser de tipos diferentes) que estão relacionados entre si. Para definir um registo usa-se a palavra-chave type. Os campos de um registo definem-se entre os carateres { e }, e cada campo tem um nome e um tipo. Para criar um registo, indica os nomes dos campos e atribui-lhes um valor entre os carateres { e }. Ao criar um registo, é obrigatório atribuir um valor a todos os campos. Os valores dos campos de uma instância de um registo podem ser acedidos com a notação de ponto.
Ao definir ou criar um registo, cada campo tem de estar numa linha separada ou, se estiverem na mesma linha, separados por pontos e vírgulas (;).
// Define a record
type Address =
{ Street: string
HouseNumber: int }
// Create a record
let oldAddress: Address =
{ Street = "Main Street"
HouseNumber = 17 }
// Single-line alternative
type ConciseAddress = { Street: string; HouseNumber: int }
let conciseAddress: ConciseAddress = { Street = "Main Street"; HouseNumber = 17 }
Como os registos são imutáveis, depois de um registo ser construído os seus valores de campo nunca podem mudar. Se quiseres alterar os valores de um registo, a palavra-chave with permite-te criar uma cópia de um registo existente, mas com novos valores para um ou mais campos.
// Copy the old address but change the house number
let newAddress: Address = { oldAddress with HouseNumber = 86 }
newAddress.Street // => "Main Street"
newAddress.HouseNumber // => 86
Os registos têm igualdade estrutural, o que significa que duas instâncias do mesmo registo com valores idênticos são equivalentes.
Além de poderes usar a notação de ponto para aceder aos campos de um registo, os registos também podem ser desconstruídos em ligações e em correspondência de padrões:
let myAddress: Address = { Street = "Broadway"; HouseNumber = 123 }
let { Street = myStreet; HouseNumber = myHouseNumber } = myAddress
match myAddress with
| { HouseNumber = 1 } -> printfn "First house"
| { HouseNumber = houseNumber; Street = street } -> printfn "House number %d on %s" houseNumber street
// => "House number 123 on Broadway
Neste exercício, és um grande fã de desporto e acabaste de descobrir uma paixão pelo basquetebol da NBA. Como és novo no basquetebol da NBA, estás a fazer uma análise aprofundada da história da NBA, a acompanhar equipas, treinadores e as suas estatísticas de vitórias e derrotas, e a compará-las entre si.
Como ainda não tens uma equipa preferida, vais também desenvolver um algoritmo para descobrir se deves torcer por uma determinada equipa.
Tens sete tarefas para te ajudar a desenvolver o teu algoritmo proprietário de torcer por uma equipa.
Define o registo Coach com os dois campos seguintes:
Name: o nome do treinador, do tipo string.FormerPlayer: indica se o treinador era um ex-jogador, do tipo bool.Define o registo Stats com os dois campos seguintes:
Wins: o número de vitórias, do tipo int.Losses: o número de derrotas, do tipo int.Define o registo Team com os três campos seguintes:
Name: o nome da equipa, do tipo string.Coach: o treinador da equipa, do tipo Coach.Stats: as estatísticas da equipa, do tipo Stats.Implementa a função createCoach, que recebe o nome do treinador e o seu estado de ex-jogador como parâmetros, e devolve o registo Coach:
createCoach "Larry Bird" true
// => { Name = "Larry Bird"; FormerPlayer = true }
Implementa a função createStats, que recebe o número de vitórias e o número de derrotas como parâmetros, e devolve o registo Stats:
createStats 58 24
// => { Wins = 58; Losses = 24 }
Implementa a função createTeam, que recebe como parâmetros o nome da equipa, o treinador e o registo, e devolve o registo Team:
let coach = createCoach "Larry Bird" true
let record = createStats 58 24
createTeam "Indiana Pacers" coach record
// => { Name = "Indiana Pacers"
// Coach = { Name = "Larry Bird"; FormerPlayer = true }
// Stats = { Wins = 58; Losses = 24 } }
Como os proprietários da NBA são impacientes, descobriste que os maus resultados da equipa levavam muitas vezes à substituição do treinador. Implementa a função replaceCoach, que recebe a equipa e o seu novo treinador como parâmetros, e devolve a equipa, mas com o novo treinador:
let coach = createCoach "Larry Bird" true
let record = createStats 58 24
let team = createTeam "Indiana Pacers" coach record
let newCoach = createCoach "Isiah Thomas" true
replaceCoach team newCoach
// => { Name = "Indiana Pacers"
// Coach = { Name = "Isiah Thomas"; FormerPlayer = true }
// Stats = { Wins = 58; Losses = 24 } }
Enquanto analisas as estatísticas, manténs listas de equipas e dos seus registos. Às vezes enganas-te e há entradas duplicadas na tua lista. Implementa a função isSameTeam, que recebe duas equipas e devolve true se forem a mesma equipa; caso contrário, devolve false:
let pacersCoach = createCoach "Larry Bird" true
let pacersStats = createStats 58 24
let pacersTeam = createTeam "Indiana Pacers" pacersCoach pacersStats
let lakersCoach = createCoach "Del Harris" false
let lakersStats = createStats 61 21
let lakersTeam = createTeam "LA Lakers" lakersCoach lakersStats
isSameTeam pacersTeam lakersTeam
// => false
Depois de analisares muitas equipas e muitos jogos, surgiu-te um algoritmo. Se uma das seguintes condições for verdadeira, torces por essa equipa:
Implementa a função rootForTeam, que recebe uma equipa e devolve true se deves torcer por essa equipa; caso contrário, return false:
let spursCoach = createCoach "Gregg Popovich" false
let spursStats = createStats 56 26
let spursTeam = createTeam "San Antonio Spurs" spursCoach spursStats
rootForTeam spursTeam
// => true
Inscreve-te no Exercism para aprenderes e dominares F# com 18 conceitos148 exercícios, e mentoria humana real, tudo grátis.