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

instance resolution error with MonadReader #64

Closed
cdepillabout opened this issue Nov 26, 2015 · 2 comments
Closed

instance resolution error with MonadReader #64

cdepillabout opened this issue Nov 26, 2015 · 2 comments

Comments

@cdepillabout
Copy link

In Haskell, the following code works fine:

import Control.Monad.Reader (MonadReader, ask)

data Environment = Production | Test | Development

data Config = Config { environment :: Environment }

class HasConfig a where
    getConfig :: a -> Config

class HasEnvironment a where
    getEnvironment :: a -> Environment

instance HasEnvironment Environment where
    getEnvironment = id

instance HasConfig Config where
    getConfig = id

instance HasEnvironment Config where
    getEnvironment = environment

baseURL :: forall m r . (MonadReader r m, HasEnvironment r) => m String
baseURL = do
    somethingThatHasEnvironment <- ask
    return $ baseURL' (getEnvironment somethingThatHasEnvironment)
  where
    baseURL' :: Environment -> String
    baseURL' Development = "http://127.0.0.1/"
    baseURL' _ = "http://example.com/"

But this similar Purescript code is not working:

module Config where

import Prelude

import Control.Monad.Reader.Class (MonadReader, ask)

data Environment = Production | Test | Development

newtype Config = Config { environment :: Environment }

class HasConfig a where
    getConfig :: a -> Config

class HasEnvironment a where
    getEnvironment :: a -> Environment

instance hasEnvironmentEnvironment :: HasEnvironment Environment where
    getEnvironment = id

instance hasConfigConfig :: HasConfig Config where
    getConfig = id

instance hasEnvironmentConfig :: HasEnvironment Config where
    getEnvironment (Config c) = c.environment

baseURL :: forall m r . (MonadReader r m, HasEnvironment r) => m String
baseURL = do
    somethingThatHasEnvironment <- ask
    return $ baseURL' (getEnvironment somethingThatHasEnvironment)
  where
    baseURL' :: Environment -> String
    baseURL' Development = "http://127.0.0.1/"
    baseURL' _ = "http://example.com/"

I get the following error:

Error in module Config:
No instance found for

  Control.Monad.Reader.Class.MonadReader _38
                                         m28

See https://github.com/purescript/purescript/wiki/Error-Code-NoInstanceFound for more information, or to contribute content related to this error.  

Is this a fundamental limitation with Purescript? Or is this just a bug?

If it is a fundamental limitation with Purescript, it would be nice to have it described on the wiki page: https://github.com/purescript/purescript/wiki/Differences-from-Haskell

@garyb
Copy link
Member

garyb commented Nov 26, 2015

I don't imagine it will, but does it work if you do this instead?

    env <- asks getEnvironment
    return $ baseURL' env

It's a temporary limitation of PureScript, due to the inability to express functional dependencies for classes, but purescript/purescript#1580

@cdepillabout
Copy link
Author

I think you're completely right. This is caused by a lack of functional dependencies. I didn't even think to check that.

Closing this for now, but hopefully Purescript gets functional dependencies in the near future 😄!

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