2009/9/28 Ben Franksen <ben.frank...@online.de>:
> To expose an impure function (!) in an API, I don't know... I mean, couldn't
> one just wrap the value like this
>
>  data Attributed a -- opaque
>
>  (&=) :: a -> Attrib -> Attributed a
>
>  mode :: Data a => Attributed a -> Mode a
>
> and thus retain a purely functional interface?

Hi Ben,

I don't think this would work because you need to be able to put the
Attributed things in the fields of your command options data type. If
they are wrapped in an "Attributed" then this may not be possible. In
particular the sample won't compile in your proposal:

data Sample = Sample {hello :: String} deriving (Show, Data, Typeable)

sample = mode $ Sample{hello = def &= text "World argument" & empty "world"}

Because the &= would return an Attributed String whereas you are
actually after a String. Essential the problem is that attributes are
attached to *fields*, but mode consumes a *record*.

The best way to do this typefully is to paramaterise the options data
type with a functor:

data Sample f = Sample {hello :: f String} deriving (Show, Data, Typeable)

Now you can do what you want, where mode :: Data a => a Attribute ->
Mode (a Id). In fact, you could even do away with Data and substitute
some sort of Foldable/Traversable as long as you were happy with the
library not being able to fill in a default argument name from the
record field name.

The current interface is the best tradeoff given what Neil is trying
to do IMHO - though the side effects make me shudder too!

Cheers,
Max
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to