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

Fixture generation for MultiParamTypeClasses #24

Closed
berdario opened this issue Oct 18, 2016 · 4 comments
Closed

Fixture generation for MultiParamTypeClasses #24

berdario opened this issue Oct 18, 2016 · 4 comments

Comments

@berdario
Copy link

Hi, I have a multiparam type class like this:

class (Monad m, MonadThrow m, FromJSON a) => MonadHTTPGet m a where
    getWith :: Wreq.Options -> String -> m (Wreq.Response a)

(I was hoping to use it, to avoid having to return m (Wreq.Response ByteString) which would force me to define an otherwise not-needed ToJSON instance for a, and encode the test values that my test code would yield when implementing getWith... not sure if there's a better alternative)

But when using mkFixture I get the following error:

Exception when trying to run compile-time code:
  src/Control/Monad/TestFixture/TH.hs:270:9-49: Irrefutable pattern failed for pattern [replacedVar]

Would it make sense for this to be implemented?

@lexi-lambda
Copy link
Contributor

Yep, we should probably fix this. At the very least, we should give a better error message than just a pattern match failure. We haven’t had a use case for it on our end, so we never implemented it, but we should support it.

I’ll look into what a fix would take.

@lexi-lambda
Copy link
Contributor

Thinking more about this, I’m not entirely sure what the “right” thing to do is here. What instance would you expect to be generated by that mkFixture call? Generating the fixture type itself is pretty straightforward:

class (Monad m, MonadThrow m, FromJSON a) => MonadHTTPGet m a where
    getWith :: Wreq.Options -> String -> m (Wreq.Response a)

data Fixture m a = Fixture
  { _getWith :: Wreq.Options -> String -> m (Wreq.Response a) }

instance (Monad m, MonadThrow m) => MonadHTTPGet (TestFixtureT Fixture w s m) ??? where

What should the ??? be?

It seems like maybe you want to write the following single-parameter typeclass, instead:

class (Monad m, MonadThrow m) => MonadHTTPGet m where
    getWith :: FromJSON a => Wreq.Options -> String -> m (Wreq.Response a)

Or is there something I’m missing?

@berdario
Copy link
Author

No, you're right... I went for the more complicated solution, but getWith :: FromJSON a => Wreq.Options -> String -> m (Wreq.Response a) works just fine.

Thanks for improving the error message already!

btw, I have stumbled upon another issue: among the constraints that I'm using there's MonadLog, which as you can see is using functional dependencies and has an existentially quantified argument in a input function.

The end result is that I get this error:

   mkDictInstanceFunc: expected method signature, given DefaultSigD Control.Monad.Log.logMessageFree (ForallT [KindedTV message_1627464288 StarT,KindedTV m_1627464289 (AppT (AppT ArrowT StarT) StarT)] [AppT (AppT (ConT Control.Monad.Log.MonadLog) (VarT message_1627464288)) (VarT m_1627464289)] (ForallT [KindedTV t_1627464290 (AppT (AppT ArrowT (AppT (AppT ArrowT StarT) StarT)) (AppT (AppT ArrowT StarT) StarT)),KindedTV n_1627464291 (AppT (AppT ArrowT StarT) StarT)] [AppT (AppT EqualityT (VarT m_1627464289)) (AppT (VarT t_1627464290) (VarT n_1627464291)),AppT (ConT Control.Monad.Trans.Class.MonadTrans) (VarT t_1627464290),AppT (AppT (ConT Control.Monad.Log.MonadLog) (VarT message_1627464288)) (VarT n_1627464291)] (AppT (AppT ArrowT (ForallT [KindedTV mon_1627464296 StarT] [AppT (ConT GHC.Base.Monoid) (VarT mon_1627464296)] (AppT (AppT ArrowT (AppT (AppT ArrowT (VarT message_1627464288)) (VarT mon_1627464296))) (VarT mon_1627464296)))) (AppT (VarT m_1627464289) (TupleT 0)))))

I haven't yet pinned down what's the exact cause for this error (when I'll do it I'll open up a new issue), but maybe for you it's obvious what exactly is going wrong here (I think that in the meanwhile I'll just wrap MonadLog in another typeclass)

Thanks again!

@lexi-lambda
Copy link
Contributor

Feel free to open an issue if you have a self-contained test case for the MonadLog problem; I’m happy to debug it and figure out what’s wrong.

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

2 participants