[Haskell-cafe] Distinct types in a list

Khudyakov Alexey alexey.skladnoy at gmail.com
Thu Jan 7 13:56:22 EST 2010


В сообщении от Четверг 07 января 2010 21:35:10 rodrigo.bonifacio написал:
> Hi all,
> 
> I have a family of parsers that return either (Success t) or (Fail), using 
the following data type:
> > data ParserResult a = Success a | Fail String
> >  deriving (Read, Show, Eq, Ord)
> >
> > isSuccess (Success _) = True
> > isSuccess (Fail _) = False
> > ...
> 
> I want to add the results of different parsers to a list. Such as:
> > m1 = parseFirstModel file1   -- it returns a ParserResult of t1
> > m2 = parseSecondModel file2  -- it returns a ParserResult of t2
> >
> > ps = [m1, m2]
> 
> In such a way that I could write something like:
> > if and (map isSuccess ps)
> >  then process m1 m2
> >  else ...
> 
> Actually, in the real program I have to check more than two input models.
>  However, since Lists do only hold elements of a same type, I couldn't
>  proceed in this way. Which improvements to the ParserResult data type
>  should I wrote in order to proceed as I want to.
> 
In short there is no easy way to this lists.

But you can make ParserResult instance of Monad and/or Applicative. 
It's is error monad in fact. You can check Control.Monad.Error to see Monad 
instance for (Either String)

With this you can write you program in applicative notation
Here computation will stop after first error. 

> m1 = parseFirstModel file1   -- it returns a ParserResult of t1
> m2 = parseSecondModel file2  -- it returns a ParserResult of t2
>
> case process <$> m1 <*> m2 of
>     (Success x) -> ...
>     (Fail x) -> ...

Or use do notation with similar results

> res = do 
>   m1 <- parseFirstModel file1
>   m2 <- parseSecondModel file2
>   return $ process m1 m2
>
> foo = case res of
>         (Success x) -> ...
>         (Fail err) -> ...

P.S. I didn't run code but I think it should work if required instances are 
defined


More information about the Haskell-Cafe mailing list