Difference between revisions of "Talk:TypeCompose"
(notes on WrappedApplicative and type composition) |
(Reply to Wolfgang -- App) |
||
Line 3: | Line 3: | ||
I have a type <hask>WrappedApplicative</hask> defined in <hask>Data.Monoid.Bonus</hask> which is part of the [[Grapefruit|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. <hask>Data.Monoid.Bonus</hask> defines an instance <hask>(Applicative a, Monoid m) => Monoid (WrappedApplicative a m)</hask>. |
I have a type <hask>WrappedApplicative</hask> defined in <hask>Data.Monoid.Bonus</hask> which is part of the [[Grapefruit|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. <hask>Data.Monoid.Bonus</hask> defines an instance <hask>(Applicative a, Monoid m) => Monoid (WrappedApplicative a m)</hask>. |
||
− | Actually, <hask>WrappedApplicative</hask> is just application of a <hask>* -> *</hask> type to a <hask>*</hask> type. So it seems much better to define a |
+ | Actually, <hask>WrappedApplicative</hask> is just application of a <hask>* -> *</hask> type to a <hask>*</hask> 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 <hask>Monoid</hask> if an applicative functor is composed with a monoid. Thereby I could get rid of <hask>WrappedApplicative</hask>. |
− | Interestingly, <hask>WrappedMonad</hask> is also type application. Maybe the above ideas could also be used to remove <hask>WrappedMonad</hask>. Maybe this would lead us to libraries which |
+ | Interestingly, <hask>WrappedMonad</hask> is also type application. Maybe the above ideas could also be used to remove <hask>WrappedMonad</hask>. Maybe this would lead us to libraries which don't introduce all kinds of wrapper types. |
What do you think? |
What do you think? |
||
-- [[User:Wolfgang Jeltsch|Wolfgang Jeltsch]] 18:23, 4 December 2007 (UTC) |
-- [[User:Wolfgang Jeltsch|Wolfgang Jeltsch]] 18:23, 4 December 2007 (UTC) |
||
+ | |||
+ | ---- |
||
+ | |||
+ | I like it. It's the same as <hask>App</hask> in <hask>Control.Compose</hask> in TypeCompose, isn't it? |
||
+ | <haskell> |
||
+ | 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) |
||
+ | </haskell> |
||
+ | I see this last definition can be improved. I just changed it to the following prettier form (using <hask>inApp2</hask>, defined in <hask>Compose</hask>): |
||
+ | <haskell> |
||
+ | instance (Applicative f, Monoid m) => Monoid (App f m) where |
||
+ | mempty = App (pure mempty ) |
||
+ | mappend = inApp2 (liftA2 mappend) |
||
+ | </haskell> |
||
+ | |||
+ | Maybe a nice infixable name instead of <hask>App</hask>. How about |
||
+ | <haskell> |
||
+ | data f :$ a = f :$ a |
||
+ | </haskell> |
||
+ | I guess I'd like two infix ops -- one left-associative and one right-associative. |
||
+ | |||
+ | By the way, have you played with <hask>(:*:)</hask>? It's been terrifically useful for me. Also the binary counterpart, <hask>(:*:)</hask>, 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 <hask>App</hask> over more specific-sounding names like<hask>WrappedMonad</hask> and <hask>WrappedApplicative</hask>. I hadn't thought to recommend that kind of change for standard libraries. |
||
+ | |||
+ | -- [[User:Conal|Conal]] 20:18, 4 December 2007 (UTC) |
Revision as of 20:18, 4 December 2007
Hello Conal,
I have a type WrappedApplicative
defined in Data.Monoid.Bonus
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. Data.Monoid.Bonus
defines an instance (Applicative a, Monoid m) => Monoid (WrappedApplicative a m)
.
Actually, WrappedApplicative
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 Monoid
if an applicative functor is composed with a monoid. Thereby I could get rid of WrappedApplicative
.
Interestingly, WrappedMonad
is also type application. Maybe the above ideas could also be used to remove WrappedMonad
. 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 App
in Control.Compose
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 inApp2
, defined in Compose
):
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 App
. How about
data f :$ a = f :$ a
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 App
over more specific-sounding names likeWrappedMonad
and WrappedApplicative
. I hadn't thought to recommend that kind of change for standard libraries.
-- Conal 20:18, 4 December 2007 (UTC)