I have a class called Foo
that owns a function gen :: Int -> [Foo]
. For instance, I could make an instance of Foo
that way:
data FooTest = FooTest Int
instance Foo FooTest where
gen n = replicate n (FooTest 0)
Now, let’s imagine I have another class called Bar
that defines a function bar :: Bar -> IO ()
. Each instance of Foo
has to be an instance of Bar
, but the Bar
implementation is quite the same for each instance. Here’s an example:
class Foo f where
gen :: Int -> [f]
class Bar b where
bar :: b -> IO ()
instance Bar Foo where -- obviously that doesn’t work
bar _ = putStrLn "bar through any Foo instance"
instance (Foo f) => Bar f where -- this needs the FlexibleInstance GHC extension first, then it still throws shit saying that the constraint is not smaller that I don’t shit
bar _ = putStrLn "bar through any Foo instance"
The problem here is I can’t find any ways to make a class an instance of another to mention the fact that any instance of the first class will share the same implementation for instancing the other class.
Any idea?
Thanks in advance.
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax: OuterClass. InnerClass innerObject = outerObject.
An object is an instance of a class. This instance can be created in another class using the new keyword. The new keyword is a very powerful keyword in Java which allows for instantiation of another class. This is how you create an object of a class in another class without using inheritance.
To create a class that inherits from another class, after the class name you'll put parentheses and then list any classes that your class inherits from. In a function definition, parentheses after the function name represent arguments that the function accepts.
Yes, that is of course possible. And it is easy to think about something where it is required. You might have a container which contains childs where the childs need a reference to the parent.
You can accomplish exactly what you want using your last instance with two extensions: FlexibleInstances
and UndecidableInstances
.
Just like the name implies, the second extension allows you to potentially write instances that do not terminate. This could lead to an infinite loop at compile time; however, the implementation is arbitrarily capped at a certain recursion depth, so you should not have actually infinite compile times.
I do not know of any way to do this without any extensions at all. However, using extensions is not inherently bad unless you might want to use other compilers in the future.
Also, a random style note: the parentheses are optional if you only have one constraint. So you could write it as:
instance Foo f => Bar f where ...
This isn't very important, but I think the second version looks better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With