Haskell Inferred instance declaration on inherited classes - haskell

I've seen cases of chains of Haskell classes that all "extend" each other (see for example, the widget/container/etc classes in gtk2hs)
class Class1 a where....
class (Class1 a)=>Class2 a where....
class (Class2 a)=>Class3 a where....
....and so on....
where all the class functions have default values that depend on one Class1 function. This works great, but makes for a really ugly "instantiation" of ClassN
Instance Class1 Object where
func x = ....
Instance Class2 Object
Instance Class3 Object
Instance Class4 Object
Instance Class5 Object
....and so on....
(I've seen code just like this in popular hackage libraries, so I'm pretty sure that at the time of the writing of the code this was a proper way to do this).
My question- Are there any newer GHC extensions that would clean this up. I've looked a bit and haven't found any. Ideally, all you really need is to decleare Object as an instance of ClassN, and give the Class1 function, the rest would be inferred.
[preemptive snarky comment :)- This indicates an "object oriented" way of thinking, you should really learn how to program functionally.
My response- I agree it is very object oriented, but code like this exists in the ecosystem today, and might very well be needed, GUI libs like gtk2hs, for example. From a practical viewpoint I need to write code like this sometimes, and I just want to simplify it.]

It is a discussed proposal to add Synonym Instances.
For example it would be possible to write next code:
type Stringy a = (Read a, Show a)
instance Stringy a where
read = ...
show = ...
in this case it would be possible to declare
type ClassAll a = (Class1 a, Class2 a, Class3 a, Class4 a)
instance ClassAll a where
foo = ...
But for now, type constraint could be used in function's signatures only, not in instances.
UPDATED
As Vittor mentions, you can find proposal here: Multi-headed instance declarations
The original proposal is a part of class aliases proposal

Related

Type hint an instance of a metaclass

I have a function which takes a class and returns an instance of that class. I'm trying to figure out how to typehint that, with a twist. Typically I would use the typing module and do something like
T = TypeVar("T", bound="BaseClass")
def foo(specific_type: Type[T]) -> T:
...
However, in my case I don't exactly want to take a class inheriting from a specific base class. What I really want to do is take a class with a specific metaclass and return an instance of that class, but I can't figure out a way to typehint that without adding some sort of dummy BaseClass. Ideally I would want the inverse of Type, something like:
M = TypeVar("M", bound="MyMetaclass")
def foo(specific_type: M) -> Instance[M]: # <-- Instance generic is made up
...
This lets me specify that foo should take an instance of MyMetaclass (which a class with metaclass=MyMetaclass is) and return an instance of that instance (an object whose class has metaclass=MyMetclass).
Is there anything in Python that lets me type hint something similar to the above?
To be clear, there is actually a base class with metaclass=MyMetaclass which I expect specific_type should probably always inherit from. However, I cannot import it into the current context without creating circular dependencies; MyMetaclass is already imported into the current context. I can work around this (I'm not asking how to organize my project), but I specifically want to know if I can type hint an instance of a class with a known metaclass like this.

Require a typeclass instance for a haskell associated type synonym

Is it possible to require that an associated type synonym of some class be an instance of some other class? E.g. with something like the following code (doesn't compile!):
class Test a where
type Foo a
instance Show (Foo a)
I would be able to rely on the fact that a Foo a is Showable regardless of the particular a in question.
Obviously I can just add more methods to the class to ensure operations I want on Foo as, but it would be nice to be able to just reuse existing classes.
Found the answer, thanks to lyxia on #haskell:
class (Show (Foo a)) => Test a where
type Foo a

Is it possible to add test&set, test&clear to the bool class?

(This is not about an atomic test and set)
All I want is to be able to write code like this:
need_cleanup = True
...
if need_cleanup.test_and_clear():
cleanup()
instead of:
if need_cleanup:
cleanup()
need_cleanup = False
IMHO this does not break anything in the bool class.
Attempts to add a method ended with:
TypeError: can't set attributes of built-in/extension type 'bool'
It is probably related to the known limitation that the bool class cannot be subclassed, but I do not want to subclass it.
Is there a way around it?
EDIT: I think I've got the answer. It is not possible, because bool is immutable. Switching from False to True (or vice versa) replaces the bool object by a new one which is identical to the True or False constant respectively. Obviously, calling a method cannot do that. The forbidden subclassing was just drawing away my attention...
You cannot.
I thought about this last night, and realized that you shouldn't be allowed to subclass bool at all! A subclass would only be useful when it has instances, but the mere existance of an instance of a subclass of bool would break the invariant that True and False are the only instances of bool! (An instance of a subclass of C is also an instance of C.) I think it's important not to provide a backdoor to create additional bool instances, so I think bool should not be subclassable.
- Guido van Rossum
In short, you can't add attributes to primitives, but you can subclass them (except when you can't).

Is there any standard implementation of the "trivial constraint", or "object class"?

I want just
class Trivial t
instance Trivial t
This is of course useless in Haskell 98 since you can just omit the constraint; but with ConstraintKinds we can have explicitly required arguments of kind * -> Constraint. Ideally, I would like to just define this as an "anonymous type-level function" \type a -> (), but that's evidently not possible.
What should I do, use something predefined or just define that class locally right where I need it (as nobody will need to access it because the instance is universal, that seems quite ok as well)?
As this appears to be quite popular, I finally pushed such a trivial-constraint class to a Hackage package.
import Data.Constraint.Trivial
id' :: Unconstrained t => t -> t
id' = id

OCL constraint to force strings not to be empty

I have a class diagram with numerous classes, some of them containing attributes of type string. I want all my strings to be of length at least 1.
The easy (yet ugly) solution is as follows:
context Class1
inv: self.attributeOfTypeString.size > 0
context Class2
inv: self.attributeOfTypeString.size > 0
...
Do you know a way to define an OCL constraints for all attributes matching a template? Something like:
global.select(attr | attr.TYPE = string) -> forall (str : string | str.size > 0)
Finally got an answer from somewhere else. I share it in case someone needs it someday.
There are three possible ways to solve the problem.
1°) The first one is to remember that multiple inheritance is allowed in UML. Therefore, we can make all classes with a string attribute inherit from a WithString class, and set the OCL constraint on this parent class. However this makes the diagrams kinda unreadable.
2°) Another possibility is to create a class String and to store an instance of this class instead of all string attributes. The problem with this encapsulation solution is the performance (use of a getter for all strings).
3°) Finally, the cleanest solution to my opinion is the following: we can declare the OCL constraint at the meta level. In the class diagram describing class diagrams, we can just state that all strings are non-empty.

Resources