ActionResult)
deadPair = do
    [x, y] ← map (\s → maybe '\0' chr (readMaybe ('0':'x':s))) <$> readLine
    pure (Char x, OutString [y])

keyName ∷ (Parser m, MonadFail m) ⇒ m [(String, String)]
keyName = do
    ['K':'E':'Y':'N':'A':'M':'E':_] ← readLine
    many (try nameValue)

descriptions ∷ (Parser m
deadKey ∷ (Logger m, Parser m, MonadFail m) ⇒ m [(Char, ActionMap)]
deadKey = do
    ["DEADKEY", s] ← readLine
    let i = maybeToList (readMaybe ('0':'x':s))
    c ← chr <$> i <$ when (null i) (tell ["unknown dead key ‘" ⊕ s ⊕ "’"])
    m ← many (isHex *> deadPair)
    pure (zip c [m])
deadKey = do
    ["DEADKEY", s] ← readLine
    let i = maybeToList (readMaybe ('0':'x':s))
    c ← chr <$> i <$ when (null i) (tell ["unknown dead key ‘" ⊕ s ⊕ "’"])
    m ← many (isHex *> deadPair)
    pure (zip c [m])