Digamos que eu tenha o seguinte registro ADT:
data Foo = Bar { a :: Integer, b :: String, c :: String }
Eu quero uma função que leva um registro e retorna um registro (do mesmo tipo) onde todos, exceto um dos campos têm valores idênticos ao passado como argumento, assim:
walkDuck x = Bar { a = a x, b = b x, c = lemonadeStand (a x) (b x) }
O procedimento acima funciona, mas para um registro com mais campos (digamos 10
), a criação de tal função envolveria muita digitação que considero desnecessária.
Existem maneiras menos tediosas de fazer o mesmo?
Respostas:
Sim, existe uma boa maneira de atualizar os campos de registro. No GHCi você pode fazer -
fonte
RecordWildCards
extensão também pode ser boa, para “desempacotar” campos em um escopo. Porém, para atualizações não é tão bom:incrementA x@Foo{..} = x { a = succ a }
updateFoo x = x.{ c = "Goodbye" }
(observe o.
operador).Este é um bom trabalho para lentes :
Então:
atualizaria o campo 'c' de 'teste' para sua string.
fonte
test $ c .~ "Goodbye"
é comolens
faria isso iirc. Não estou dizendo que seja intuitivo, mas uma vez que você conhece os operadores, espero que seja tão fácil quanto$
.Você não precisa definir funções auxiliares ou empregar lentes. O Haskell padrão já tem o que você precisa. Vejamos o exemplo de Don Stewart:
Então você pode simplesmente dizer
test { c = "Goodbye" }
para obter um registro atualizado.fonte