[Haskell-cafe] matching constructors

Brandon Michael Moore brandon at its.caltech.edu
Fri Mar 5 12:41:41 EST 2004



On Fri, 5 Mar 2004, Vadim Zaliva wrote:

> Hi!
>
> I am new to Haskell, but I have background in various programming
> languages (including Lisp)
>
> I have very basic question, if there is a way to match algebraic types
> constructors besides
> use of pattern matching. I wrote today code like this:
>
> data Flag = Verbose |
>              Input String  |
>              Output String |
>              Filter String
>              deriving Show
>
> instance Eq Flag where
>      Verbose  == Verbose  = True
>      Input  _ == Input  _ = True
>      Output _ == Output _ = True
>      Filter _ == Filter _ = True
>      _ == _ = False
>
> findFlag :: Flag -> [Flag] -> Flag
> findFlag f [] = f
> findFlag y (x:xs) = if x == y then x else findFlag y xs
>
> If there is a cleaner way to implement findFlag and Eq Flag?
>
> Vadim

It looks like you are doing some sort of option processing. There have
been some suggestions recently for better approaches on the haskell list.
See the thread "High-level technique for program options handling" from
January.

The basic idea there is to define a record type holding your options in
the most useful form for your program, and turn your arguments into
functions that transfrom such a record, rather than values you need to
analyze. The example in Tomasz Zeilonka's post has exactly the option
structure of your code.



At the lower level of remimplementing your functions I can suggest a few
things.

It's probably overkill, but the Data typeclass provides an operation that
takes a value and returns the constructor used. Add "Data" to the list of
typeclasses you want to derive, and you can write your equality function
as (GHC only)

 x == y = toConstr x == toConstr y

For your findFlag function, the library function "find" is nearly what
you want, except it returns a value in Maybe rather than taking a default:

findFlag :: Flag -> [Flag] -> Maybe Flag
findFlag f fs = find (==f) fs

You could use the "maybe" function (Maybe a -> b -> (a->b) -> b) to supply
the default.


Brandon

> --
> "La perfection est atteinte non quand il ne reste rien a ajouter, mais
> quand il ne reste rien a enlever."  (Antoine de Saint-Exupery)
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>



More information about the Haskell-Cafe mailing list