50 lines
1.6 KiB
Text
50 lines
1.6 KiB
Text
load "bool.quox"
|
||
load "string.quox"
|
||
load "maybe.quox"
|
||
load "io.quox"
|
||
|
||
def if = bool.if
|
||
|
||
def Nil = list.Nil; def Cons = list.Cons
|
||
|
||
def0 Direction : ★ = {left, right}
|
||
|
||
namespace direction {
|
||
def from-char : Char → Maybe Direction =
|
||
λ c ⇒
|
||
let0 Res = Maybe Direction in
|
||
letω L = char.from-ℕ 0x4C; R = char.from-ℕ 0x52 in
|
||
case char.dup c return Res of { [c] ⇒
|
||
if Res (char.eq c L) (Just Direction 'left)
|
||
(if Res (char.eq c R) (Just Direction 'right)
|
||
(Nothing Direction))
|
||
}
|
||
|
||
-- skips unknown characters, e.g. spaces
|
||
def from-string : String → List Direction =
|
||
let0 Res = List Direction in
|
||
λ str ⇒
|
||
list.foldr Char Res (Nil Direction)
|
||
(λ c ⇒ maybe.fold Direction (Res → Res)
|
||
(λ lst ⇒ lst) (Cons Direction) (from-char c))
|
||
(string.to-list str)
|
||
}
|
||
|
||
def which : 0.(A : ★) → ω.(A × A) → Direction → A =
|
||
λ A xy d ⇒ case d return A of { 'left ⇒ fst xy; 'right ⇒ snd xy }
|
||
|
||
def lookup : 0.(A B : ★) → ω.(ω.A → Bool) → ω.(List (A × B)) → Maybe B =
|
||
λ A B p ⇒
|
||
list.foldlω (A × B) (Maybe B) (Nothing B)
|
||
(λ st x ⇒ maybe.foldω B (Maybe B)
|
||
(if (Maybe B) (p (fst x)) (Just B (snd x)) (Nothing B))
|
||
(λ ok ⇒ Just B ok) st)
|
||
|
||
def0 Map : ★ = List (String × String × String)
|
||
|
||
def next : ω.Map → ω.String → ω.Direction → Maybe String =
|
||
λ map here d ⇒
|
||
maybe.foldω (String × String) (Maybe String)
|
||
(Nothing String)
|
||
(λ res ⇒ Just String (which String res d))
|
||
(lookup String (String × String) (string.eq here) map)
|