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

Fmap Gets Context Wrong in Nested Contexts #192

Closed
turtlegrammar opened this issue Mar 23, 2017 · 5 comments · Fixed by #203 or nubank/cats#3
Closed

Fmap Gets Context Wrong in Nested Contexts #192

turtlegrammar opened this issue Mar 23, 2017 · 5 comments · Fixed by #203 or nubank/cats#3

Comments

@turtlegrammar
Copy link

To reproduce:

(require '[cats.core :as cats])
(require '[cats.monad.either :as either])
(require '[cats.monad.maybe :as maybe])

(cats/mlet [x (either/right 1)
            z (either/right (maybe/from-maybe (cats/fmap #(do (prn "okay, here")
                                                              (inc %))
                                                         (maybe/just 1))
                                              0))]
           (either/right z))

;; => Right 1

The expected behavior: "okay, here" is printed, and the return is Right 2.
The actual behavior: the fmap never applies the function to Just 1, instead returning it as is.

I think this happens because fmap determines the context is Either, and Just 1 is not Right 1. See this example:

(require '[cats.context :as ctx])
(require '[cats.core :as cats])
(require '[cats.monad.either :as either])
(require '[cats.monad.maybe :as maybe])

(cats/mlet [x (either/right 1)]
           (either/right (ctx/infer (maybe/just 1))))
;; => Right #<Either>

I thought you could fix this by swapping the order of the first two cond clauses in context/infer -- first, check if v satisfies p/Contextual, and if so, get the context from v. Fall back to getting *context*. But, when I made this change, some tests started failing, and I don't have the time to figure out why.

@luminusian
Copy link

#188 seems related.

@sovelten
Copy link
Collaborator

Swapping the conds also solved my issue with cats using the wrong context. I can try to make a PR for this, but it would be nice to hear from the maintainers if this is the right thing to do.

@barconference
Copy link

@EricVM
I'm not a maintainer, but it would be great if you could make a PR.

@niwinz
Copy link
Member

niwinz commented Apr 20, 2017

@EricVM +1 to the PR

@sovelten
Copy link
Collaborator

sovelten commented May 16, 2017

There are two tests that break when we try to infer from p/Contextual before using the dynamic context. Both of them are related to overriding the default context of p/Contextual with a dynamic context.

So, some of the possibilities are:

  • Leave unchanged and never use nested contexts inside a dynamic context
  • Prefer contexts inferred from p/Contextual and lose the ability to override default context

I find neither of these possibilities are good enough. I tried to circumvent this by defining a macro with-context-override when you need to override the context from p/Contextual #203

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