
On 12 November 2014 07:59, Larry Lee
Hi
I have a very simple problem. I have a class and want to define a function in that class that returns a different instance of the same class.
I tried accomplishing this as follows:
class A a where f :: A b => a -> b
This type signature says "I can convert my instance of type `a' to any instance of this type class `b'... as chosen by the *caller* of this function". i.e. if you have instances for Foo, Bar and Baz, then "f Foo" isn't fixed to just Bar: the caller can choose any instance it likes (which is usually not what you want).
This fails however when I try to instantiate it. For example:
instance A String where f x = x
This instance only works if the `b' in the type signature of `f' is also String, rather than being chosen by the caller.
I get an error message that makes absolutely no sense to me:
src/CSVTree.hs:12:9: Could not deduce (b ~ [Char]) from the context (A b) bound by the type signature for f :: A b => String -> b at src/CSVTree.hs:12:3-9 `b' is a rigid type variable bound by the type signature for f :: A b => String -> b at src/CSVTree.hs:12:3 In the expression: x In an equation for `f': f x = x In the instance declaration for `A String' make: *** [compile] Error 1
This is saying "The instance definition requires the `b' type to be [Char] (i.e. String), but there's no requirement/ability in the definition of the type to have such a constraint/requirement."
Can someone please explain: how I can achieve my goal; and why my code is failing; simply and in plain English.
Depending on what exactly you want, there are three options: * If you want each type to convert to itself, then change the type of `f' to be just "a -> a" * If you want a one-to-many mapping (i.e. given `a', I know there's precisely one possible value of `b'), then use either Multi-Param Type Classes (MPTCs) + Functional Dependencies or else an associated Type Family alias within the type class to denote that relationship. * If you have a many-to-many relationship (Foo can convert to Foo or Baz, Bar can convert only to Baz and Baz can convert to anything), then use an MPTC (though this will in general require an instance for every possible pairing).
Thanks, Larry _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com http://IvanMiljenovic.wordpress.com