[Haskell-cafe] Re: Laziness and Either

apfelmus apfelmus at quantentunnel.de
Wed Apr 23 07:12:16 EDT 2008


John Goerzen wrote:
> On Mon April 21 2008 3:26:04 pm Magnus Therning wrote:
>> In order to allow lazy decoding I ended up exporting decode' as well:
>>
>>   decode' :: String -> [Maybe Word8]
> 
> I take it that in a situation like this, you'd have either:
> 
> []   -- success with empty result
> 
> a list full of Just x
>      -- success with valid results
> 
> a list with 0 or more Just x, followed by one Nothing
>      -- an error
> 
> Makes sense to me.  What impact does this have on performance?

I think that using  [Maybe a]  for this purpose is too fine-grained, I 
would use a custom list type

   data River a = a :< (River a) | Done | Error

(I didn't want to call it  Stream  because that name is too overloaded 
already and  PartialList  is too long :) The three constructors 
correspond to the three cases you mention. In particular, Error takes 
the role of the last  Nothing .

In other words, we just replace the usual end of list [] with another 
data type. Thus, the general version is

   data River b a = a :< (River a) | End b

Of course, this type is isomorphic to

   River b a ~ (b, [a])

The latter just puts the end result up front which is the original idea 
for lazy parsing: report the error  b  but also return a (partial) 
result  [a] .

> Also, I wonder if there is some call for tools in Data.Either to support this 
> type of usage?  For example:
> 
> type EitherList a b = [Either a b]
> 
> then some functions such as, say, mapEither or foldEither that act like 
> try/catch: a special function to use for an exception, and otherwise 
> they "unwrap" the Right side passing it along to others.

The  River  thing has the drawback that you have to rewrite all the 
standard list functions, but since you're ready to accept that for in 
the case of  [Either a b]  anyway, you can as well use the  River  thing.


Regards,
apfelmus



More information about the Haskell-Cafe mailing list