-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem with bind and contexts #3
Comments
One of the design decisions of this library is that all the Parsers you can define have to consume some of their input. This makes deciding whether it is safe to perform a recursive call trivial (if you have already run a first parser, then you can go ahead). As a consequence it is not possible to write You can define this parser like so: instead of using Definition float_Q : Parser Chars ascii M Q n :=
decimal_N >>= fun x : N =>
match x with
| N0 => (fun x => Qmake x 1%positive) <$> decimal_int
| Npos p => (fun x => Qmake x p) <$> decimal_int
end. |
Alternatively, because there is no real control flow dependency between the value of Definition float_Q_cast (x : N) (y : Z) : Q :=
Qmake y (match x with
| N0 => 1
| Npos p => p end).
Definition float_Q' : Parser Chars ascii M Q n :=
(float_Q_cast <$> decimal_N) <*> decimal_int. |
Well, look at that. Thanks for the fast response! I'm getting closer and closer to something that works... :)
|
@gallais Success! I still have a bit of math to do inside Require Import Category.
Require Import Sized.
Require Import Combinators.
Require Import Numbers.
Require Import NEList.
Require Import Char.
Require Import Running.
Require Import Indexed.
Require Import Coq.NArith.NArith.
Require Import Coq.QArith.QArith.
Require Import Coq.Strings.String.
Require Import Ascii.
Local Open Scope char.
Require Import Coq.Lists.List.
Section Helpers.
Context
{M : Type -> Type}
`{RF : RawFunctor M}
`{RA : RawApplicative M}
`{RM : RawMonad M}
`{RT : RawAlternative M}
{Chars : nat -> Type} `{Sized Chars ascii}
{n : nat}.
Definition decimal_digit_N : Parser Chars ascii M N n :=
alts ((0 <$ exact "0")%N
:: (1 <$ exact "1")%N
:: (2 <$ exact "2")%N
:: (3 <$ exact "3")%N
:: (4 <$ exact "4")%N
:: (5 <$ exact "5")%N
:: (6 <$ exact "6")%N
:: (7 <$ exact "7")%N
:: (8 <$ exact "8")%N
:: (9 <$ exact "9")%N
:: nil).
Definition decimal_N : Parser Chars ascii M N n :=
let convert ds := foldl (fun ih d => 10 * ih + d)%N ds 0%N
in Combinators.map convert (nelist decimal_digit_N).
Definition float_Q : Parser Chars ascii M Q n :=
((fun x '(y, z) =>
Qmake x (match z with
| N0 => 1
| Npos x => x
end))
<$> (decimal_int <& exact "."))
<*> ((((fun x y => (length (toList x), y))
<$> nelist (0 <$ exact "0")%N)
<*> decimal_N)
<|> ((fun x => (0%nat, x))
<$> decimal_N)).
End Helpers.
Section ArithmeticLanguage.
Context
{Toks : nat -> Type} `{Sized Toks ascii}
{M : Type -> Type} `{RawMonad M} `{RawAlternative M}.
Record Coords := {
coordTime : N;
coordLatitude : Q;
coordLongitude : Q
}.
Record Language (n : nat) : Type := MkLanguage
{ _expr : Parser Toks ascii M (NEList Coords) n
}.
Arguments MkLanguage {_}.
Definition language (n : nat) : Language n :=
MkLanguage
(nelist
(((Build_Coords
<$> (decimal_N <& spaces))
<*> (float_Q <& spaces))
<*> (float_Q <& space))).
Definition expr : [ Parser Toks ascii M (NEList Coords) ] :=
fun n => _expr n (language n).
Definition float_expr : [ Parser Toks ascii M Q ] :=
fun n => @float_Q _ _ _ _ _ _ _ _ _ n.
End ArithmeticLanguage.
Lemma test_float_Q : check "10.2" float_expr.
Proof.
vm_compute; constructor.
Qed.
Definition newline := String "013"%char EmptyString.
Lemma test_expr : check ("10 10.2 10.2" ++ newline ++
"10 10.2 10.2" ++ newline)%string expr.
Proof.
vm_compute; constructor.
Qed. |
The float_Q_cast is much cleaner, but I still need to track how many zeroes occurred after the decimal point, so I know what to multiply the numerator by. And it needs to parse the period. :) |
Nice! This is what I'd do: Definition float_Q_cast : (Z * option (NEList ascii) * N) -> Q :=
fun '((x , zeros) , z) =>
Qmake x (match z with | N0 => 1 | Npos p => p end).
Definition float_Q : Parser Chars ascii M Q n :=
float_Q_cast
<$> decimal_int
<&> (char "." &?> nelist (char "0"))
<&> decimal_N. The idea is that a parser for a (potentially empty) list is a parser for a My strategy in general is to collect all the data by using various Btw: I didn't know about |
I have the following code right now:
When I tried to type check
float_Q
, I get:As you can see, there are somehow three
RawFunctor M
instances in scope, which I don't quite understand. I've tried various combinations of explicit arguments, but I was wondering if you could help me understand what I'm doing wrong here?The text was updated successfully, but these errors were encountered: