Mercurial > feed
changeset 10:edc2b467f818
Add a version of Feed.app which threads state.
author | Karn Kallio <kkallio@eka> |
---|---|
date | Thu, 09 Jun 2011 12:59:27 -0430 |
parents | f19beef42ceb |
children | 43c3fbd8527a |
files | src/ur/feed.ur src/ur/feed.urs |
diffstat | 2 files changed, 32 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ur/feed.ur Tue May 31 09:21:49 2011 -0430 +++ b/src/ur/feed.ur Thu Jun 09 12:59:27 2011 -0430 @@ -218,28 +218,29 @@ val fetch = FeedFfi.fetch -fun app [internal ::: Type] [data ::: Type] (p : pattern internal data) (f : data -> transaction {}) (doc : document) : transaction {} = +fun app' [internal ::: Type] [data ::: Type] [acc ::: Type] (p : pattern internal data) (f : data -> acc -> transaction acc) + (doc : document) (acc : acc) : transaction acc = let - fun recur xml state = + fun recur xml acc state = case String.seek xml #"<" of - None => return () + None => return acc | Some xml => if xml <> "" && String.sub xml 0 = #"/" then case String.seek xml #"\x3E" of - None => return () + None => return acc | Some xml => case p.ExitTag state of - None => recur xml p.Initial + None => recur xml acc p.Initial | Some state => case p.Finished state of - None => recur xml state + None => recur xml acc state | Some (data, cont) => - f data; - recur xml (if cont then state else p.Initial) + acc <- f data acc; + recur xml acc (if cont then state else p.Initial) else if xml <> "" && String.sub xml 0 = #"?" then case String.seek xml #"\x3E" of - None => return () - | Some xml => recur xml state + None => return acc + | Some xml => recur xml acc state else if xml <> "" && String.sub xml 0 = #"!" then if String.lengthGe xml 3 && String.sub xml 1 = #"-" && String.sub xml 2 = #"-" then let @@ -252,18 +253,18 @@ else skipper xml in - recur (skipper (String.suffix xml 3)) state + recur (skipper (String.suffix xml 3)) acc state end else case String.seek xml #"]" of - None => return () + None => return acc | Some xml => case String.seek xml #"\x3E" of - None => return () - | Some xml => recur xml state + None => return acc + | Some xml => recur xml acc state else case String.msplit {Needle = " >/", Haystack = xml} of - None => return () + None => return acc | Some (tagName, ch, xml) => let fun readAttrs ch xml acc = @@ -329,22 +330,25 @@ | Some (cdata, xml) => (xml, Some cdata) in case p.EnterTag {Tag = tagName, Attrs = attrs, Cdata = cdata} state of - None => recur xml p.Initial + None => recur xml acc p.Initial | Some state => case p.Finished state of None => (case (if ended then p.ExitTag state else Some state) of - None => recur xml p.Initial + None => recur xml acc p.Initial | Some state => case p.Finished state of - None => recur xml state + None => recur xml acc state | Some (data, cont) => - f data; - recur xml (if cont then state else p.Initial)) + acc <- f data acc; + recur xml acc (if cont then state else p.Initial)) | Some (data, cont) => - f data; - recur xml (if cont then state else p.Initial) + acc <- f data acc; + recur xml acc (if cont then state else p.Initial) end in - recur doc p.Initial + recur doc acc p.Initial end + +fun app [internal ::: Type] [data ::: Type] (p : pattern internal data) (f : data -> transaction {}) (doc : document) : transaction {} = + app' p (fn data acc => f data) doc ()
--- a/src/ur/feed.urs Tue May 31 09:21:49 2011 -0430 +++ b/src/ur/feed.urs Thu Jun 09 12:59:27 2011 -0430 @@ -69,6 +69,11 @@ val fetch : string -> transaction document (* Retrieve a document by URL. *) +val app' : internal ::: Type -> data ::: Type -> acc ::: Type -> pattern internal data + -> (data -> acc -> transaction acc) -> document -> acc -> transaction acc +(* Find all matches of a pattern in a document, running an imperative function + * on the data returned by each match while threading through some state. *) + val app : internal ::: Type -> data ::: Type -> pattern internal data -> (data -> transaction {}) -> document -> transaction {} (* Find all matches of a pattern in a document, running an imperative function * on the data returned by each match. *)