Reputation: 1218
I have the following module structure:
Module A:
module ModuleA where
newtype Parser p = P (String -> Maybe (p, String))
parse :: Parser p -> String -> Maybe (p, String)
parse (P p) = p
item :: Parser Char
item = P (\inp -> case inp of
[] -> Nothing
(x: xs) -> Just (x, xs))
Module B:
module ModuleB where
...
instance Alternative Parser where
empty = P (\inp -> Nothing)
(P a) <|> (P b) = P (\inp -> case a inp of
Nothing -> b inp
Just (x, v) -> Just (x, v)
)
Module C:
module ModuleC where
import ModuleA
import ModuleB
import Data.Char
conditionalParser :: (Char -> Bool) -> Parser Char
conditionalParser f = do
x <- item
if f x then return x else empty
The code does not compile, with error Variable not in scope: empty :: Parser Char
. If I move the Alternative
instance into the ModuleC
module, it compiles.
How can I import the Alternative
instance definition, so that it can be safely used? I have also tried using a qualified reference for empty
, with no success.
Upvotes: 1
Views: 53
Reputation: 80754
You are importing the instance definition from ModuleB
just fine. It's the class definition that you're not importing, and it's in the class, not the instance, that the empty
method is declared.
Add this at the top of ModuleC
:
import Control.Applicative
That should do it.
Or, alternatively, you can re-export the Applicative
class from ModuleB
.
Note also that it's generally considered unsound to define instances in a module separate from both the type and the class. This may lead to subtle unexpected results with choosing the right instance down the line. This is called "orphan instance" and there is even a compiler warming against it.
Upvotes: 2