
I am trying to create an instance of a class for String types. I have the following: class Foo a where mkFoo :: a -> String instance Foo String where mkFoo x = x and receive the following error: test.hs:9:0: Illegal instance declaration for `Foo String' (The instance type must be of form (T a b c) where T is not a synonym, and a,b,c are distinct type variables) In the instance declaration for `Foo String' Failed, modules loaded: none. I see that in general I am not able to create an instance of a class for any type [a], where a is a specific type. I can work around it by wrapping my Strings in some other data type but I'd like to understand why it's not possible. Any insight would be appreciated. -Adam

adam:
I am trying to create an instance of a class for String types. I have the following:
class Foo a where mkFoo :: a -> String
instance Foo String where mkFoo x = x
and receive the following error:
test.hs:9:0: Illegal instance declaration for `Foo String' (The instance type must be of form (T a b c) where T is not a synonym, and a,b,c are distinct type variables) In the instance declaration for `Foo String' Failed, modules loaded: none.
I see that in general I am not able to create an instance of a class for any type [a], where a is a specific type.
Ok.
class Foo a where mkFoo :: a -> String
N.B. The instance type must be of form (T a b c), where T is not a synonym. One portable solution, introduce a newtype.
newtype Strung = S String instance Foo Strung where mkFoo (S x) = x
*Main> mkFoo (S "foo") "foo" Alternatively, use -fglasgow-exts :)
instance Foo String where mkFoo = id
$ ghci -fglasgow-exts A.hs *Main> mkFoo "foo" "foo" -- Don

On 29/09/2006, at 12:44 PM, Donald Bruce Stewart wrote:
Alternatively, use -fglasgow-exts :)
instance Foo String where mkFoo = id
$ ghci -fglasgow-exts A.hs *Main> mkFoo "foo" "foo"
And just to follow up what Don said, this feature of GHC is described here: http://www.haskell.org/ghc/docs/latest/html/users_guide/type- extensions.html

Adam,
class Foo a where mkFoo :: a -> String
instance Foo String where mkFoo x = x
In addition to making use of language extensions or wrapper types, you could go with the following workaround in just plain Haskell 98: import List class MkFoo a where mkFoo :: a -> String mkFooList :: [a] -> String mkFooList = concat . intersperse ", " . map mkFoo instance MkFoo Char where mkFoo = (: []) mkFooList = concatMap mkFoo instance (MkFoo a) => MkFoo [a] where mkFoo = mkFooList For instance:
mkFoo False "no"
mkFoo [False, True] "no, yes"
mkFoo 'h' "h"
mkFoo "haskell" "haskell"
The same approach is taken for implementing Show in the standard libraries. Note that it requires you to fix the type constructors that are to be treated in a special manner ([] in the above example). HTH, Stefan
participants (4)
-
Adam Hupp
-
Bernie Pope
-
dons@cse.unsw.edu.au
-
Stefan Holdermans