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

Add some variadic function to simplify dependency invocation? #1

Closed
danidiaz opened this issue Jan 16, 2021 · 3 comments
Closed

Add some variadic function to simplify dependency invocation? #1

danidiaz opened this issue Jan 16, 2021 · 3 comments

Comments

@danidiaz
Copy link
Owner

Invoking functions stored in a record-of-functions while in a ReaderT / DepT is kind of verbose. I asked about that in SO some time ago.

Perhaps one of the answers to that question could be added to this package.

@danidiaz
Copy link
Owner Author

If we want to leave the function polymorphic on the monad, as in bc3aca3 , then we have a big problem: the typeclass that implements the variadic function can't be sure if the m is a function or not, and gets very confused.

* Could not deduce (Call'
                      r0
                      (TheMonad' (m ()) (IsFunction (m ())))
                      (m ())
                      (IsFunction (m ())))
    arising from a use of `call'
  from the context: (MonadReader e m, HasLogger e m,
                     HasRepository e m)
    bound by the type signature for:
               mkController :: forall e (m :: * -> *).
                               (MonadReader e m, HasLogger e m, HasRepository e m) =>
                               Int -> m Int

@danidiaz
Copy link
Owner Author

Another thing that I tried here fefa627 was to have a MonadDep typeclass. The idea was that, given that concrete monads know if they are different from (a ->) or not, I could delegate the variadic logic on each concrete monad.

MonadDep had a type family that produced different constraints depending on the monad, and the constraints were applied ton the method. I'm surprised that it compiled at all!

Alas, it doesn't work:

test\tests.hs:43:3: error:
    * Could not deduce: WhatConstraintToUse r0 m0 r0 (String -> m ())
        arising from a use of `callx'
      from the context: (MonadDep e m, HasLogger e m, HasRepository e m)
        bound by the type signature for:
                   mkController :: forall e (m :: * -> *).
                                   (MonadDep e m, HasLogger e m, HasRepository e m) =>
                                   Int -> m Int

Similar problem as before: polymorphic monad = trouble.

@danidiaz
Copy link
Owner Author

A consolation price is that one can write auxiliary functions for each HasX typeclass, like this:

logger' :: (MonadReader r m, HasLogger r m) => String -> m ()
logger' msg = do
    f <- asks logger
    f msg

And use them like this:

mkController :: (MonadReader e m, HasLogger e m, HasRepository e m) => Int -> m Int
mkController x = do
  logger' "I'm going to insert in the db!"

It's more boilerplate though.

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

No branches or pull requests

1 participant