Agda: parse a string with numbers

前端 未结 3 1965
渐次进展
渐次进展 2021-01-13 12:19

I am trying to parse a string with natural numbers in Agda. e.g., the result of stringListToℕ \"1,2,3\" should be Just (1 ∷ 2 ∷ 3 ∷ [])

My

3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-13 12:30

    I had a go at it trying not to be clever and using simple recursive functions rather than stdlib magic. parse xs m ns parses xs by recording the (possibly empty) prefix already read in m while keeping the list of numbers already parsed in the accumulator ns.

    If a parsing failure happens (non recognized character, two consecutive ,, etc.) everything is thrown away and we return nothing.

    module parseList where
    
    open import Data.Nat
    open import Data.List
    open import Data.Maybe
    open import Data.Char
    open import Data.String
    
    isDigit : Char → Maybe ℕ
    isDigit '0' = just 0
    isDigit '1' = just 1
    isDigit '2' = just 2
    isDigit '3' = just 3
    isDigit _   = nothing
    
    attach : Maybe ℕ → ℕ → ℕ
    attach nothing  n = n
    attach (just m) n = 10 * m + n
    
    Quote : List Char → Maybe (List ℕ)
    Quote xs = parse xs nothing []
      where
        parse : List Char → Maybe ℕ → List ℕ → Maybe (List ℕ)
        parse []         nothing  ns = just ns
        parse []         (just n) ns = just (n ∷ ns)
        parse (',' ∷ tl) (just n) ns = parse tl nothing (n ∷ ns)
        parse (hd ∷ tl)  m        ns with isDigit hd
        ... | nothing = nothing
        ... | just n  = parse tl (just (attach m n)) ns
    
    stringListToℕ : String → Maybe (List ℕ)
    stringListToℕ xs with Quote (toList xs)
    ... | nothing = nothing
    ... | just ns = just (reverse ns)
    
    open import Relation.Binary.PropositionalEquality
    
    test : stringListToℕ ("12,3") ≡ just (12 ∷ 3 ∷ [])
    test = refl
    

提交回复
热议问题