
I seem to be forever writing code that looks like this: decode :: String -> (SKI,String) decode (c:cs) = case c of 'S' -> (S,cs) 'K' -> (K,cs) 'I' -> (I,cs) '*' -> let (e0,cs0) = decode cs; (e1,cs1) = decode cs1 in (e0 :@: e1, cs1) In other words, lots and lots of functions with signatures like foo :: [Foo] -> (Bar,[Foo]) that likes to call itself recursively, or that gets called from somewhere else. Is there a Better Way(tm) to do this? It looks like such a common idiom that you'd expect to see "something" in the libraries somewhere. (I remember being puzzled that there was no library function for creating a Cartesian product of two lists. Puzzled until I realised that the monadic nature of lists make it utterly trivial to do this by hand anyway! So it's not always obvious to know what you're looking for...)

Andrew Coppin
I seem to be forever writing code that looks like this:
decode :: String -> (SKI,String) decode (c:cs) = case c of 'S' -> (S,cs) 'K' -> (K,cs) 'I' -> (I,cs) '*' -> let (e0,cs0) = decode cs; (e1,cs1) = decode cs1 in (e0 :@: e1, cs1)
This looks like parsing to me. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

More generally, that's unfoldr:
Prelude> :t Data.List.unfoldr
Data.List.unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr represents the end of the unfold explicitly (using Nothing)
instead of implicitly (using the empty list).
/g
On 27 Jun 2007 20:26:56 +0100, Jon Fairbairn
Andrew Coppin
writes: I seem to be forever writing code that looks like this:
decode :: String -> (SKI,String) decode (c:cs) = case c of 'S' -> (S,cs) 'K' -> (K,cs) 'I' -> (I,cs) '*' -> let (e0,cs0) = decode cs; (e1,cs1) = decode cs1 in (e0 :@: e1, cs1)
This looks like parsing to me.
-- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- The man who'd introduced them didn't much like either of them, though he acted as if he did, anxious as he was to preserve good relations at all times. One never knew, after all, now did one now did one now did one.

J. Garrett Morris wrote:
More generally, that's unfoldr:
Prelude> :t Data.List.unfoldr Data.List.unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr represents the end of the unfold explicitly (using Nothing) instead of implicitly (using the empty list).
Duh... of course it does. :-S Silly thing is, I use unfoldr all the time - for converting integers to bits. *sigh* Of course, that solves the problem of just wanting to chop the input into chunks. It works less well if you want to do complicated recursive stuff. But IIRC the Parsec library supports parsing of arbitrary tokens (although presumably they have to be in Eq?) so maybe I should revise that...
participants (4)
-
Andrew Coppin
-
J. Garrett Morris
-
Jon Fairbairn
-
Tillmann Rendel