I have three data declarations in the different modules:
data Data1 = Data1
  { id :: UUID
  , field2 :: String
  , field3 :: Int
  }
data Data2 = Data2
  { id :: UUID
  , field1112 :: String
  , field4433 :: String
  }
data Data3 = Data3
  { id :: UUID
  , field22 :: Double
  , field344 :: Int
  }
And a class declaration:
class MyClass1 a where
  method1 ....
How can I specify a constraint for MyClass1 so that only Data1, Data2 and Data3 can be instantiated by MyClass1 because they all have the field id?
I tried the following, but it didn't seem right to me and I got errors:
-- in the different module
class MyDataBase a where
  id :: a -> UUID
-- in the module Data1.hs
instance MyDataBase Data1 where
  id d1 =  
-- in the module Data2.hs
-- and so on....
class (MyDataBase a) => MyClass1 a where
  method1 .... = -- calling 
				
                        
What about types you don't know about that also have that field?
In general, you can accomplish things like that with Lens (regular Haskell records are IMHO unusable); if you name your fields
_Data1Idand_Data2Id(customizable), you'll get aHasIdclass withidlens and instances for that class forData1andData2. Then you can use that class as a constraint further.Of course you don't have to use
makeFieldsand you can write the instances yourself. Not sure why you'd do that, though.You didn't specify what errors you got, but I bumped off
UndecidableInstances. Here's how to get around "Constraint is no smaller than the instance head" error:This will allow you to use any type that satisifies B in a A context (but as Carsten pointed out, it's also an antipattern of sorts).