[Haskell-cafe] Parsing different types, same typeclass

Chris Wong chrisyco+haskell-cafe at gmail.com
Sun Nov 18 03:08:56 CET 2012


Hello José,

> So, I have a typeclass "Action" which defines method "run":
>
> class Action a where
>     run :: a -> Int
>
> (snipped)
>
> Now, I want to parse either "A" or "B" from a String.
> I was thinking about something like this...
>
> parseAction :: (Action a, Read a) => String -> a
> parseAction str
>     | "(A " `isPrefixOf` str = (read :: String -> A) str
>     | "(B " `isPrefixOf` str = (read :: String -> B) str
>
> The problem is that when calling "parseAction" I get "ambiguous type
> constraints". How to implement a parse function for two distinct
> types that share the same typeclass "Action". Because after calling
> "parseAction" I don't whether "A" or "B" was returned: I only care
> that they are "Action" instances so I can call "run".

The problem with your current type:

    (Action a, Read a) => String -> a

is that it actually means:

    For any type that implements Action and Read, I can convert a
string to that type.

This is wrong because if a user of your module added another type C,
your function wouldn't be able to handle it -- it only "knows" about A
and B. That is what GHC is trying to tell you.

How you can solve this problem depends on what you're trying to do. If
there is a finite number of actions, you can merge them into a single
type and remove the type class altogether:

    data Action = A Int | B Int
        deriving (Read, Show)

    run :: Action -> Int
    run (A x) = x
    run (B x) = x

    parse :: String -> Action
    parse = read

If you have a possibly unlimited number of possible actions, there are
many approaches to this -- including, as Stephen said, existential
types. However, it's hard to decide on a proper solution without
knowing what you're actually trying to do.

Chris

> Best regards,
> José
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list