
Even with "ReallyLiberalTypeSynonyms" you can't have (f . g) ~ h as that
would involve a partial application in a non type synonym, so there is no
issue with unification.
(.) only means something with all 3 arguments applied so that it can be
expanded, but you can still allow it to be formally passed around inside
other type synonyms so long as the final type synonym has all of its
arguments expanded.
type (.) f g x = f (g x)
type Foo = (.) Bar
Foo doesn't fully instantiate (.) but you can keep eta expanding it until
it does.
type Foo g x = (.) Bar g x = Bar (g x)
is a perfectly legitimate definition. You can do this expansion
automatically pretty easily. Given such a type synonym you can answer how
many arguments it must have before it is a real type.
At a use site Foo is not a type until it has been applied to two more
arguments, just like the eta expanded form above. Foo ~ Baz doesn't type
check for the same reason given
type Id a = a
you can't talk about Id ~ Bar. Id isn't a type. It needs an argument before
it makes sense.
This is what I mean by "ReallyLiberalTypeSynonyms". We actually wound up
with these by accident in the Ermine compiler we use at work, and they
turned out to be quite useful and harmless in practice.
We don't have this power today, but we do have LiberalTypeSynonyms, which
gets us close.
-Edward
On Wed, Nov 2, 2016 at 7:36 PM, Ken Bateman
Wouldn't there also be a problem with type unification? When unifying ((f . g) a) and (h b) do you set ((f . g) ~ h) or ((g a) ~ b)?
On Nov 2, 2016 6:28 PM, "Edward Kmett"
wrote: On Wed, Nov 2, 2016 at 3:11 PM, Index Int
wrote: Edward, I don't quite follow why you think that (.) is needed here. Monad transformers take two parameters, so your example is not type-correct, whereas the original one is.
Indeed, I appear to have hyper-corrected that example.
-Edward
On Wed, Nov 2, 2016 at 5:24 PM, Edward Kmett
wrote: +1, but the operator you're looking for in App there would actually be a type level version of (.).
type App a = ExceptT Err $ ReaderT Config $ LogT Text $ IO a
type App = ExceptT Err . ReaderT Config . LogT Text . IO
which would need
type (.) f g x = f (g x) infixr 9 .
to parse
-Edward
On Tue, Nov 1, 2016 at 7:13 PM, Elliot Cameron
wrote: Folks,
Has there been a discussion about adding a type-level operator "$"
that
just mimics "$" at the value level?
type f $ x = f x infixr 0 $
Things like monad transformer stacks would look more "stack-like" with this:
type App = ExceptT Err $ ReaderT Config $ LogT Text IO
Elliot Cameron
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries