Implementation using Transit

State and message types

Nothing special here. We define the state and message types like we did in the previous examples. By using Variants, we have no constraint on how the labels are named; we can use any type-level string we want: numbers, lowercase letters, etc. Traditional ADTs wouldn’t give us this flexibility.

type State = Variant
  ( "1" :: {}
  , "2" :: {}
  , "3" :: {}
  , "4" :: {}
  , "5" :: {}
  )

type Msg = Variant
  ( "a" :: {}
  , "b" :: {}
  , "c" :: {}
  , "d" :: {}
  , "e" :: {}
  , "f" :: {}
  , "g" :: {}
  , "h" :: {}
  )

🗎 test/Examples/HouseSantaClaus.purs L27-L44

Type-level specification

The transit specification follows the same pattern as in the previous example.

type SantaTransit =
  Transit
    :* ("1" |< "a" >| "2")
    :* ("2" |< "b" >| "3")
    :* ("3" |< "c" >| "5")
    :* ("5" |< "d" >| "4")
    :* ("4" |< "e" >| "1")
    :* ("1" |< "f" >| "3")
    :* ("2" |< "g" >| "4")
    :* ("3" |< "h" >| "4")

🗎 test/Examples/HouseSantaClaus.purs L46-L55

The Update Function

Until now, we have always manually defined the update function. In most cases this will be the way to go. But you may have noticed that in some cases this is sheer boilerplate. We can let the compiler generate the update function for us by using the mkUpdateAuto function. This works if the following conditions are met:

Both conditions are met in our case, so we can use mkUpdateAuto to generate the update function for us. We could have used it in the Door example and the Bridges of Königsberg example as well.

update :: State -> Msg -> State
update =
  mkUpdateAuto @SantaTransit

🗎 test/Examples/HouseSantaClaus.purs L57-L59

↑ Back to top