March 24, 2015 Re: D's type classes pattern ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to matovitch | On Tuesday, 24 March 2015 at 16:56:13 UTC, matovitch wrote:
> 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 ;)).
Ali already mentioned the difference between "==" and ":".
In addition to that, template specializations (like `Bar(T : Foo)(T t)`) and template constraints (like `Bar(T)(T t) if(is(T : Foo))`) are similar but generally not interchangeable.
A template with a specialization is considered a better match than one without. Whereas a template constraint doesn't add to the quality of the match.
An example:
module test;
import std.stdio;
void f(T)(T t) {writeln("generic");}
void f(T : int)(T t) {writeln("with specialization");}
void f(T)(T t) if(is(T : Object)) {writeln("with constraint");}
void main()
{
f("some string"); /* -> "generic" */
f(42); /* -> "with specialization" */
version(none) f(new Object); /* Doesn't compile, because it matches both the generic version and the one with the constraint. */
}
|
March 25, 2015 Re: D's type classes pattern ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | Thanks for the precisions on template constraint and template specialization...Indeed wath I want to do look like isInputRange constraint. Haskell have something like : //(Pseudo D-Haskell) void foo(InputRange R)(R r); //D equivalent void foo(R)(R r) if (isInputRange(R)); Except they call them type classes instead of template constraint and it is check at runtime instead of compile time for D. I am curious to know how isInputRange is implemented since I wanted to do kind of the same but I am afraid it's full of (ugly) traits and template trickeries where haskell type classes are quite neat and essentially a declaration of an interface. Let say I want to be able to add the type my algo deal with...I could do an isAddable wich looks if a+b compiles with traits...I wondered if you could check statically that the type could implement an interface *if it wanted to* that is, without inheriting it... |
March 25, 2015 Re: D's type classes pattern ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to matovitch | matovitch: > I am curious to know how isInputRange is implemented since I > wanted to do kind of the same but I am afraid it's full of (ugly) > traits and template trickeries where haskell type classes are > quite neat and essentially a declaration of an interface. Take a look at the sources and learn. They are sometimes tricky to get right, but it's not a problem of ugly syntax. > I wondered if you could check statically that the type could > implement an interface *if it wanted to* that is, without > inheriting it... Template constraints don't require inheritance. Bye, bearophile |
March 25, 2015 Re: D's type classes pattern ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, 25 March 2015 at 08:55:14 UTC, bearophile wrote: > matovitch: > >> I am curious to know how isInputRange is implemented since I >> wanted to do kind of the same but I am afraid it's full of (ugly) >> traits and template trickeries where haskell type classes are >> quite neat and essentially a declaration of an interface. > > Take a look at the sources and learn. They are sometimes tricky to get right, but it's not a problem of ugly syntax. > > >> I wondered if you could check statically that the type could >> implement an interface *if it wanted to* that is, without >> inheriting it... > > Template constraints don't require inheritance. > > Bye, > bearophile Yes I know that you don't need to inherit some InputRange interface to be able to check a user defined type is an input range. And template constraints are more powerful/general than type classes but it's harder to get right for the beginner. I will definetly look at the code anyway. I was looking at : interface IInputRange(InputRange) {...} class TypeClass(T,I) : I!T { alias t this; T t; } void foo(InputRange) (InputRange inputRange) if (isInstanciable(TypeClass!(InputRange, IInputRange))); |
Copyright © 1999-2021 by the D Language Foundation