Dopo anni passati a compilare moduli e ad aspettare, hai finalmente ottenuto la licenza bancaria. Questo significa che ora puoi aprire ufficialmente la tua banca, evviva!
La tua prima priorità è far funzionare i sistemi informatici. Dopo una giornata di duro lavoro, sai già aprire e chiudere conti, oltre a gestire prelievi e versamenti.
Siccome non avevi voglia di scrivere i test, inviti alcuni amici a dare una mano a collaudare il sistema. Però, dopo appena cinque minuti, uno dei tuoi amici sostiene di aver perso dei soldi! Anche se sei sicuro che il tuo codice sia privo di bug, inizi a spulciare i log per indagare.
Ah, già, proprio come sospettavi: la colpa è del tuo amico! Ha condiviso le sue credenziali di test con un altro amico, e insieme hanno cospirato per fare versamenti e prelievi dallo stesso conto in parallelo. Chi mai farebbe una cosa del genere?
Mentre sostieni che sia fisicamente impossibile accedere al proprio conto in parallelo, il tuo amico ti fa notare con aria di sufficienza che le regole bancarie ti impongono di supportarlo. Quindi niente supporto bancario in parallelo, niente via libera per il lancio. Sospirando, ti riprometti mentalmente di occupartene domani. Questo sposterà la data di lancio di almeno un altro giorno, ma vabbè...
Il tuo compito è implementare conti bancari che supportino l'apertura e la chiusura, i prelievi e i depositi di denaro.
Poiché è possibile accedere ai conti bancari in molti modi diversi (internet, telefoni cellulari, addebiti automatici), il software bancario deve permettere di accedere ai conti in modo sicuro da più thread/processi (la terminologia dipende dal linguaggio di programmazione che usi) in parallelo. Ad esempio, possono verificarsi molti depositi e prelievi in parallelo; devi assicurarti che non ci siano race condition tra il momento in cui leggi il saldo del conto e quello in cui imposti il nuovo saldo.
Dovrebbe essere possibile chiudere un conto; le operazioni su un conto chiuso devono fallire.
Per completare questo esercizio devi implementare le seguenti funzioni:
openAccount: chiamata all'inizio di ogni test. Restituisce un BankAccount.closeAccount: chiamata alla fine di ogni test.getBalance: restituisce il saldo del conto bancario.updateBalance: incrementa il saldo del conto bancario dell'importo indicato.L'importo può essere negativo nel caso di un prelievo.
Il saldo iniziale del conto bancario dovrebbe essere 0.
Troverai già una dichiarazione di dati fittizia e le firme dei tipi, ma sta a te definire le funzioni e creare un tipo di dati, un newtype o un sinonimo di tipo che abbia senso.
Se hai bisogno di aiuto, ecco alcune risorse aggiuntive:
Iscriviti a Exercism per imparare e padroneggiare Haskell con 107 esercizi e il mentoring di persone reali, tutto gratis.