Hello Conal,

I have a type

defined in

which is part of the

grapefruit-data package. I introduced it because I wanted to make use of the fact that for every applicative functor a and every monoid m, a m is again a monoid.

defines an instance

(Applicative a, Monoid m) => Monoid (WrappedApplicative a m)

.
Actually,

is just application of a

type to a

type. So it seems much better to define a "composition" type which "composes" a unary type with a nullary type. Such a "composition" would be an instance of

if an applicative functor is composed with a monoid. Thereby I could get rid of

.
Interestingly,

is also type application. Maybe the above ideas could also be used to remove

. Maybe this would lead us to libraries which don't introduce all kinds of wrapper types.

What do you think?

-- Wolfgang Jeltsch 18:23, 4 December 2007 (UTC)

I like it. It's the same as

in

in TypeCompose, isn't it?

newtype App f a = App { unApp :: f a }
instance (Applicative f, Monoid m) => Monoid (App f m) where
mempty = App (pure mempty )
App a `mappend` App b = App (liftA2 mappend a b)

I see this last definition can be improved. I just changed it to the following prettier form (using

, defined in

):

instance (Applicative f, Monoid m) => Monoid (App f m) where
mempty = App (pure mempty )
mappend = inApp2 (liftA2 mappend)

Maybe a nice infixable name instead of

. How about

I guess I'd like two infix ops -- one left-associative and one right-associative.

By the way, have you played with

? It's been terrifically useful for me. Also the binary counterpart,

, e.g., with arrows (and deep arrows). With these tools, Eros can carry around and compose various kinds of info (values, UIs, types, code, pretty-printings, ...), without impacting the code base. Very powerful.
And yes, I strongly agree with generic names like

over more specific-sounding names like

and

. I hadn't thought to recommend that kind of change for standard libraries.

-- Conal 20:18, 4 December 2007 (UTC)