Lab 4 is due Thursday, October 19 at 11:59pm.

Remember to require cs151-core and typed/test-engine/racket-tests as usual.

This week, you will practice list programming, including filters and aggregations. You will write functions to process transaction data involving a set of fictional banks, as described below.

First, copy the following data definitions from this page.

(define-type Bank
  (U 'Lake 'Left 'Right))

(define-struct Account
  ([bank   : Bank]
   [number : Integer]))

(define-struct Transaction
  ([from   : Account]
   [to     : Account]
   [amount : Integer]))

(define-type Ledger (U 'LNil LCons))
(define-struct LCons
  ([first : Transaction]
   [rest  : Ledger]))
There are three banks in this system, named "Lake Bank", "Left Bank" and "Right Bank". None of these banks actually exists, as far as we know. A bank is represented by one of three symbols, and a bank account consists of a bank symbol and an integer account number. By convention an account number is a large positive integer, but at no place in this code must we verify that property. A transaction is an exchange of money between two accounts, the account ("from") from which the money is drawn, and the account ("to") into which the money is paid. The amount of money is represented by an integer number of cents. By convention, the transaction amount must be a positive integer, as there is no need to record zero-money transactions, and any "negative" transaction can be written as the same transaction with the accounts swapped. Finally, a "ledger" is a unary tree, i.e., a linked list, of zero or more transactions.

Your task this week is to write the following batch of functions dealing mostly with ledgers, and all along the theme of money and transactions. As usual, you are free to write additional functions over and above what we've specified here, and are encouraged to do so. Having said that, you must not change the names or types in any of the following specifications.

(: money-string : Integer -> String)
;; given a number of cents, produce a string of the form "$12.34"
;; note: negative amounts of money are allowed and appear in parentheses
;; zero cents must produce"$0.00"
;; one cent must produce "$0.01"
;; minus one cent must produce "($0.01)"
;; 102 cents must produce "$1.02"

(: same-bank? : Account Account -> Boolean)
;; return true if the accounts are at the same bank

(: account=? : Account Account -> Boolean)
;; equality test for accounts

(: from-bank? : Bank Transaction -> Boolean)
;; return true if the transaction originated at (is "from") the given bank

(: trx-volume : Ledger -> Integer)
;; count the number of transactions on the ledger

(: trx-total : Ledger -> Integer)
;; return the total amount of money (in cents) involved in all transactions
;; note the result must be nonnegative

(: trx-from-account : Account Ledger -> Ledger)
;; return all transactions that originate (are "from") the given account

(: trx-from-bank : Bank Ledger -> Ledger)
;; return all transactions that originate (are "from") the given bank

(: ledger-net : Bank Ledger -> Integer)
;; Computes the net amount of money that flows in or out of
;; the given bank on the whole ledger.
;; Note that money that moves within the same bank -- for example,
;; a transaction from Lake Bank to Lake Bank -- has no effect on its net.
;; Only transactions that result in money flowing into the given bank
;; or money flowing out of the given bank affect its net.
;; The result is an integer, negative for a net loss for the bank,
;; zero for no change, and positive for a net gain.

(: at-or-above : Integer Ledger -> Ledger)
;; return all transactions whose amount is greater than or
;; equal to the given threshold

(: largest : Ledger -> Ledger)
;; compute the ledger of zero or more of the transactions
;; whose transaction amount is equal to the largest transaction
;; amount on the ledger
    

Please submit one file, lab4.rkt, in a lab4 directory in your repository.