Jump to page: 1 2
Thread overview
D's type classes pattern ?
Mar 24, 2015
matovitch
Mar 24, 2015
matovitch
Mar 24, 2015
matovitch
Mar 24, 2015
matovitch
Mar 24, 2015
matovitch
Mar 24, 2015
weaselcat
Mar 24, 2015
matovitch
Mar 24, 2015
matovitch
Mar 24, 2015
Ali Çehreli
Mar 24, 2015
anonymous
Mar 25, 2015
matovitch
Mar 25, 2015
bearophile
Mar 25, 2015
matovitch
Mar 24, 2015
Ali Çehreli
March 24, 2015
Hi,

It's been a long time since I coded some d code... sorry I take
the lazy way asking for advices. :D

Lets say I want to implement some generic algorithm. I would like
to checks the types passed to my algorithm implements a specific
interface.

interface IStuff(Stuff)
{
     void foo();
}

class TypeClass(T, I) : I(T)
{
     alias this T;
}

void myAwesomeAlgo(Stuff) (TypeClass!(Stuff, IStuff) stuff)
{
     stuff.foo();
}


Well it seems that I have worked out my question in trying to
formulate it...Would something like this work ?
March 24, 2015
More like :

import std.stdio;

interface IStuff(Stuff)
{
     void foo();
}

class TypeClass(T, I) : I(T)
{
     alias this stuff;
     T stuff;
}

void myAwesomeAlgo(Stuff) (TypeClass!(Stuff, IStuff) stuff)
{
     stuff.foo();
}

struct MyStuff
{
    void foo()
    {
        writeln("Hello World !");
    }
}

void main()
{
    alias TypeStuff = TypeClass!(MyStuff, IStuff);
    TypeStuff stuff;
    myAwesomeAlgo(stuff);
}

Doesn't compile btw :

kmeans.d(8): Error: members expected
kmeans.d(8): Error: { } expected following aggregate declaration
kmeans.d(8): Error: Declaration expected, not '('
kmeans.d(12): Error: unrecognized declaration
March 24, 2015
Well, just follow that link to the code...it almost compile : http://dpaste.com/3JNP0QD.
March 24, 2015
well, alias this is the issue here.

interface I
{
    void foo();
}

struct S
{
    void foo() {}
}

class C : I
{
    S s;
    alias this s;
}

don't compile...if you have any idea to do otherwise I am greatly interested. Thanks !
March 24, 2015
To resume my goal (last lonely message I promise), how can you statically check a type implement an interface without making this type inherit the interface (otherwise std.traits would do it) ?

ps : it seems to me that this is exactly what the haskell compiler do with type classes <- layman opinion
March 24, 2015
On Tuesday, 24 March 2015 at 15:51:00 UTC, matovitch wrote:
> Hi,
>
> It's been a long time since I coded some d code... sorry I take
> the lazy way asking for advices. :D
>
> Lets say I want to implement some generic algorithm. I would like
> to checks the types passed to my algorithm implements a specific
> interface.
>
> interface IStuff(Stuff)
> {
>      void foo();
> }
>
> class TypeClass(T, I) : I(T)
> {
>      alias this T;
> }
>
> void myAwesomeAlgo(Stuff) (TypeClass!(Stuff, IStuff) stuff)
> {
>      stuff.foo();
> }
>
>
> Well it seems that I have worked out my question in trying to
> formulate it...Would something like this work ?

interface Foo{
}
void Bar(T : Foo)(T t){
}

but interfaces enable runtime polymorphism, you can just accept the interface itself
void Fun(Foo foo){
}
March 24, 2015
On Tuesday, 24 March 2015 at 16:44:54 UTC, weaselcat wrote:
> On Tuesday, 24 March 2015 at 15:51:00 UTC, matovitch wrote:
>> Hi,
>>
>> It's been a long time since I coded some d code... sorry I take
>> the lazy way asking for advices. :D
>>
>> Lets say I want to implement some generic algorithm. I would like
>> to checks the types passed to my algorithm implements a specific
>> interface.
>>
>> interface IStuff(Stuff)
>> {
>>     void foo();
>> }
>>
>> class TypeClass(T, I) : I(T)
>> {
>>     alias this T;
>> }
>>
>> void myAwesomeAlgo(Stuff) (TypeClass!(Stuff, IStuff) stuff)
>> {
>>     stuff.foo();
>> }
>>
>>
>> Well it seems that I have worked out my question in trying to
>> formulate it...Would something like this work ?
>
> interface Foo{
> }
> void Bar(T : Foo)(T t){
> }
>
> but interfaces enable runtime polymorphism, you can just accept the interface itself
> void Fun(Foo foo){
> }


Thanks, just to be clear :

void Bar(T : Foo)(T t){
}

is the same as

void Bar(T)(T t) if (is(T == Foo)){
}

and it is checked only at compile time ? (for the runtime I know that what interface were meant for ;)).


March 24, 2015
Wait no ! In that case my type will have to inherit the interface...I don't want that, checking without inheriting...I know thats weird.
March 24, 2015
On 03/24/2015 09:56 AM, matovitch wrote:

> just to be clear :
>
> void Bar(T : Foo)(T t){
> }

That means "if T can implicitly be converted to Foo".

>
> is the same as
>
> void Bar(T)(T t) if (is(T == Foo)){
> }

That means "if T is exactly Foo".

> and it is checked only at compile time ?

Yes to both.

Ali

March 24, 2015
On 03/24/2015 08:50 AM, matovitch wrote:

> Lets say I want to implement some generic algorithm. I would like
> to checks the types passed to my algorithm implements a specific
> interface.

I think you are looking for template constraints. Look at isInputRange's implementation:


https://github.com/D-Programming-Language/phobos/blob/master/std/range/primitives.d#L143

Then you can do:

void foo(Range)(Range range)
   if (isInputRange!Range)    // <--
{
    // ...
}

I have some explanation and examples here:


http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.named%20template%20constraint

Ali

« First   ‹ Prev
1 2