Add Queue datatype - #3084
Conversation
|
When adding new functionality, we tend to make somewhat larger PRs than when fixing things. In particular, a bunch of properties should be proved too. The main reason is that quite often the proofs reveal when some of functionality was written in a correct-but-hard-to-use (or reason about) manner. So basically all of #3083 will need to be done in this PR. On the other hand, asking for reviews of the intermediate steps is a good idea. |
| toList empty = [] | ||
| toList (queue dq-hd dq-tail eq) = dq-hd ∷ (dq-tail ++ (reverse eq)) | ||
|
|
||
| -- Create a Queue from a List, such that the elements |
There was a problem hiding this comment.
Probably consider fromSnocList too.
There was a problem hiding this comment.
Some alternative suggestions as to implementation.
Against @JacquesCarette , and because I'm a bit more 'OO-minded', I tend to put things like Empty/isEmpty as manifest fields of the record, because then I don't have to think about the scope management. Similarly toList, because all the pieces are at-hand without further ado... but YMMV.
As for references for this kind of implementation, probably Okasaki's "Purely functional data structures" would be the go-to citation?
Oh, and: fix-whitespace!
There is also https://doi.org/10.1017/S0956796800001489 |
So, eg.: toList-fromList : toList (fromList xs) ≡ xsThe converse direction requires some simulation relation on |
Co-authored-by: jamesmckinna <31931406+jamesmckinna@users.noreply.github.com>
Co-authored-by: jamesmckinna <31931406+jamesmckinna@users.noreply.github.com>
| to𝔹 : Q A → Bool | ||
| to𝔹 = isYes ∘ empty? |
There was a problem hiding this comment.
Similarly, should this be called null? or isEmpty? or what, in general...
|
Note: sorry for pushing a file with holes in! |
| {!!} ≡⟨⟩ | ||
| {!!} | ||
| ++-[] : ∀ {xs ys : List A} → (xs ++ ys) ≡ [] → ys ≡ [] | ||
| ++-[] {xs = []} {ys = []} xs++ys≡[] = xs++ys≡[] |
There was a problem hiding this comment.
Note that the equivalent properties in Data.Nat.Properties have more complex names:
m+n≡0⇒m≡0 : ∀ m {n} → m + n ≡ 0 → m ≡ 0
m+n≡0⇒n≡0 : ∀ m {n} → m + n ≡ 0 → n ≡ 0I personally would expect ++-[] to be a proof that xs ++ [] ≡ xs
There was a problem hiding this comment.
There are two hard things in computer science...
Descriptive names is definitely something I need to get a hold of!
|
Should instances bet put into a |
Yes to instances going into a [I'll do a full pass on all the comments / code later.] |
|
Oh no! Some properties of |
|
hmmm... circular dependencies? Does splitting the |
|
I think it would rather be splitting Or maybe moving the definitions used in the instance of |
| --- Smart Constructor | ||
|
|
||
| queue : List< A → List A → Queue A | ||
| queue [] ys = mkQ (fromList> (reverse ys)) [] (const []) |
There was a problem hiding this comment.
Ca the call to fromList> (reverse ys) be fused into something simpler?
Will eventually resolve #3083. Uses the two-list method mentioned in #3072 (but in a PR not generated by an LLM this time).
There may be some poor stylistic choices due to my unfamiliarity with the standard library, for which I am sorry! There are some 'low hanging' basic operations that could still be added, but I think those would be good for separate PRs.