
Am Samstag 11 April 2009 16:41:50 schrieb Michael Mossey:
Quentin Moser wrote:
On Sat, 11 Apr 2009 02:02:04 -0700 Michael Mossey
wrote: This is a matter of good coding style (in the sense of modularity, maintanability, etc.).
As you've seen it, the authors have first started with a (>>?) function that allows them to combine Maybes, that is to combine functions with a possibility of error.
...
Thanks for the detailed explanation. I like how you show that the original
? function, and the method of signaling either an error or a result, could have been written with ==> notation.
But, I'm still confused on a point. Let me put it this way. The authors wrote:
-- file: ch10/Parse.hs -- import the Word8 type from Data.Word parseByte :: Parse Word8 parseByte = getState ==> \initState -> case L.uncons (string initState) of Nothing -> bail "no more input" Just (byte,remainder) -> putState newState ==> \_ -> identity byte where newState = initState { string = remainder, offset = newOffset } newOffset = offset initState + 1
Why couldn't they have avoided getState by writing
parseByte = Parse ( \initState -> case L.unconcs (string initState) of ... ... newOffset = offset initState +1 )
...because a parser is by definition a function that takes ParseState as its input. I understand you are saying that in future chapters they may introduce new capabilities that fit within this framework, so maybe that's what I'm not seeing. Maybe they will redefine getState (or something equivalent) so that it does more than grab the unchanged state from the Parse.
In a real library, the constructor Parse would not be exported, to allow later changing the implementation of the Parse type without breaking user code. So user code like parseByte cannot access the constructor and must use the exported API (getState, putState, identity, bail, ...).
But I'm curious to know if my second implementation works the same as the first, in theory.
As long as the constructor is accessible, yes.
Thanks