rseInformation <$> try kbdField
    <|> set' _parseShiftstates <$> try shiftstates
    <|> set' _parseKeys <$> klcKeys
    <|> set' _parseLigatures <$> try ligatures
    <|> set' _parseDeadKeys <$> try deadKey
    <|> (∅) <$ try descriptions
    <|> (∅) <$ try languageNames
    <|> (∅) <$ try keyName
    <|> (∅) <$ try endKbd
    <|> (try nameValue >>= (uncurry field >$> set' _parseInformation))
    <|> (readLine >>= \xs → (∅) <$ tell ["uknown line ‘" ⊕ show xs ⊕ "’"])
  where
    set' ∷ Monoid α ⇒ ASetter α α' β β' → β' → α'
    set' f = flip (set f) (∅)
    field ∷ Logger m ⇒ String → String → m Information
    field "COPYRIGHT" = pure ∘ set' _copyright ∘ Just
    field "COMPANY" = pure ∘ set' _company ∘ Just
    field "LOCALENAME" = const (pure (∅))
    field "LOCALEID" = pure ∘ set' _localeId ∘ Just
    field "VERSION" = pure ∘ set' _version ∘ Just
    field f = const $ (∅) <$ tell ["unknown field ‘" ⊕ f ⊕ "’"]

kbdField ∷ (Parser m, MonadFail m) ⇒ m Information
kbdField = do
    ["KBD", l1, l2] ← readLine
    pure ∘ set _name l1 ∘ set _fullName l2 $ (∅)

shiftstates ∷ (Parser m, MonadFail m) ⇒ m
klcLayout ∷ (Logger m, Parser m, MonadFail m) ⇒ m KlcParseLayout
klcLayout = many >$> mconcat $
        set' _parseInformation <$> try kbdField
    <|> set' _parseShiftstates <$> try shiftstates
    <|> set' _parseKeys <$> klcKeys
    <|> set' _parseLigatures <$> try ligatures
    <|> set' _parseDeadKeys <$> try deadKey
    <|> (∅) <$ try descriptions
    <|> (∅) <$ try languageNames
    <|> (∅) <$ try keyName
    <|> (∅) <$ try endKbd
    <|> (try nameValue >>= (uncurry field >$> set' _parseInformation))
    <|> (readLine >>= \xs → (∅) <$ tell ["uknown line ‘" ⊕ show xs ⊕ "’"])
  where
    set' ∷ Monoid α ⇒ ASetter α α' β β' → β' → α'
    set' f = flip (set f) (∅)
    field ∷ Logger m ⇒ String → String → m Information
    field "COPYRIGHT" = pure ∘ set' _copyright ∘ Just
    field "COMPANY" = pure ∘ set' _company ∘ Just
    field "LOCALENAME" = const (pure (∅))
    field "LOCALEID" = pure ∘ set' _localeId ∘ Just
    field "VERSION" = pure ∘ set' _version ∘ Just
    field f = const $ (∅) <$ tell ["unknown field ‘" ⊕ f ⊕ "’"]
klcLayout = many >$> mconcat $
        set' _parseInformation <$> try kbdField
    <|> set' _parseShiftstates <$> try shiftstates
    <|> set' _parseKeys <$> klcKeys
    <|> set' _parseLigatures <$> try ligatures
    <|> set' _parseDeadKeys <$> try deadKey
    <|> (∅) <$ try descriptions
    <|> (∅) <$ try languageNames
    <|> (∅) <$ try keyName
    <|> (∅) <$ try endKbd
    <|> (try nameValue >>= (uncurry field >$> set' _parseInformation))
    <|> (readLine >>= \xs → (∅) <$ tell ["uknown line ‘" ⊕ show xs ⊕ "’"])
  where
    set' ∷ Monoid α ⇒ ASetter α α' β β' → β' → α'
    set' f = flip (set f) (∅)
    field ∷ Logger m ⇒ String → String → m Information
    field "COPYRIGHT" = pure ∘ set' _copyright ∘ Just
    field "COMPANY" = pure ∘ set' _company ∘ Just
    field "LOCALENAME" = const (pure (∅))
    field "LOCALEID" = pure ∘ set' _localeId ∘ Just
    field "VERSION" = pure ∘ set' _version ∘ Just
    field f = const $ (∅) <$ tell ["unknown field ‘" ⊕ f ⊕ "’"]