Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enter and Raw don't interact well #157

Closed
alpmestan opened this issue Jul 17, 2015 · 8 comments
Closed

Enter and Raw don't interact well #157

alpmestan opened this issue Jul 17, 2015 · 8 comments
Assignees

Comments

@alpmestan
Copy link
Contributor

As per the error illustrated here, or this one where you can see the same (cryptic) error message, Enter and Raw don't play well together. That's because Enter tries to "peef off a monad stack" of Application, which reduces to trying to peel a monad stack off of Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived, which reduces to trying to peel a monad stack off of IO ResponseReceived per the "distribute the arguments" instances of Enter, which usually won't work.

We need an instance for Enter that says that whatever the source and destination monads for Enter, if we encounter Raw/Application please leave it alone, as-is.

Something like:

instance Enter Application (m :~> n) Application where
  enter _ app = app
@jkarni
Copy link
Member

jkarni commented Jul 18, 2015

Not sure this is the right instance. An alternative is:

instance Enter (Request -> (Response -> m ResponseReceived) -> m ResponseReceived) (m :~> n) (Request -> (Response -> n ResponseReceived) -> n ResponseReceived) where
   enter ...

And even what we currently do sort of makes sense, when seen from a particular perspective.

I'm not suggesting those options instead. I just worry about muddling the semantics of enter with special cases.

I think perhaps a more principled way would be to have a separate newtype, NoEntry, that has the instance you mention. And then people can wrap whatever they want in that.

@alpmestan
Copy link
Contributor Author

That (NoEntry) would clutter API types though, it kind of feels like a hack.There's a case to be made for Raw remaining Raw whatever the monad stack. A Raw WAI Application is just that. From this perspective, it makes sense to leave Application alone, as is. Judging from the problems folks have had with this, I'd argue this is the least surprising thing to do.

@jkarni
Copy link
Member

jkarni commented Jul 18, 2015

There's a case to be made for Raw remaining Raw whatever the monad stack

Yes, there is a case. But there also is a case for the opposite claim: if I thread some Reader monad through my stack, Raw should get it too. How else am I going to e.g. get my database connection info (well, I can pass it in as an extra argument, but that's exactly the sort of thing enter was designed to avoid).

it kind of feels like a hack.

It's the same design we were discussing w.r.t to Canonicalize. I agree that if it's the only example of such a newtype, it'll feel like a hack, but my longer-term impression is that we're going to have other reasons for doing this in the future. And if instead of the question "how do we get Raw to work in this situation", we ask "what is the general approach we would like to have to prevent the propagation of DSL description modifiers", I think something like NoEntry feels much more natural.

That (NoEntry) would clutter API types though

This I agree with.

Another alternative is to have Raw expect a newtype-wrapped Application everywhere.

@alpmestan
Copy link
Contributor Author

Hmm. So ServerT Raw m = m Application ?

@jkarni
Copy link
Member

jkarni commented Jul 18, 2015

I changed my mind :) . 👍 on your original idea. I think the conceptual backing for NoEnter etc. should be to prevent further exploration for non-simple types (ones with :> and :<|>, basically) in the DSL. Raw is simple.

@codedmart
Copy link
Contributor

@jkarni @alpmestan any problems with closing this? After speaking with @jkarni briefly on irc things are changing with enter as it stands, or could be changing.

@soenkehahn
Copy link
Contributor

Note that there's this workaround: https://groups.google.com/d/msg/haskell-servant/jhDWkAZixuI/Hkm8CBAuEQAJ

@phadej
Copy link
Contributor

phadej commented Jun 8, 2017

This is fixed in 0.11.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants