Skip to main content

Day 18 - Conditional data

Skills: 4

Pre-reading: 6.1.1.2, 6.1.2.3, 6.1.3.2, 6.1.3.3

Intro (10 mins)

  • Sometimes, rather than data being composed of different parts, as we saw last time, data comes in multiple, incompatible, forms.
  • For example, a payment system might need to track the source of payment, which could be:
    • Cash, with no further information
    • Check, with the bank account number and routing number (and possibly more information -- account number, check number, etc)
    • Credit Card, with the credit card number (and possibly more information -- expiration date, security code, etc)
  • This doesn't fit into the pattern of structured data, since different alternatives have different, incompatible, components. A security code makes no sense for a check, and a check number has no bearing on a credit card, and all of the extra fields make no sense for cash.
  • Instead, this type of data is conditional -- data that takes the shape of exactly one of several variants.
  • We can define the above using the same data mechanism:
    data PaymentMethod:
    | cash
    | credit(card-number :: String, expiry :: String)
    | check(bank-account :: String, routing :: String, check-number :: Number)
    end
  • Note that there is one data type PaymentMethod, but three ways of constructing it -- cash, credit, and check.
  • We create examples of this data similarly to how we did with structured data:
    payment-1 = cash
    payment-2 = credit("1111-2222-3333-4444", "09/26")
    payment-3 = check("987654321", "111", 55)
  • To use conditional data, however, we can't use the dot notation for field lookup, like with structured data, since given a PaymentMethod, we don't know which variant we have! Instead, we use a new language feature called cases, which allows you to write down what to do in each possible case of the data, creating names for fields in the variants that have fields:
      fun display-payment(p :: PaymentMethod) -> String:
    cases (PaymentMethod) p:
    | cash => "Paid in cash"
    | credit(cn, exp) => "Paid by credit card " + string-from-number(string-length(cn))
    | check(acc, rout, num) => "Paid by check from account " + acc
    end
    end

Class Exercises (40 mins)

TODO

Wrap-up (5 mins)

TODO