D中的特征可以用于类型类吗?
|
我是D的新手,我正在寻找一种使用类似Haskell的类型类进行编程的好方法,例如D中的函子,Monoids等。
在Tango或Phobos中是否实现了类似的功能?
我听说过一些特性,这些特性可以对某些属性进行编译时类型检查。它们可以用于类型类吗?
我已经尝试了一些模板专业化,并提出了以下建议:
// Monoid.d
// generic Monoid gets called when there is no instance of Monoid for Type T
class Monoid(T) {
pragma(msg, \"Type is not a Monoid\");
}
// Monoid instance for double
class Monoid(T:double) {
static T mzero() { return 0; }
static T mappend(T a, T b ) { return a + b;}
}
// Monoid instance for int
class Monoid(T:int) {
static T mzero() { return 0; }
static T mappend(T a, T b ) { return a + b;}
}
然后将类型参数需要为Monoid的通用算法表示为:
template genericfunctions() {
T TestMonoid(T,N = Monoid!T)(T a) {
return N.mappend(N.mzero(),a);
}
}
但是,如果要忽略模板参数,则必须导入所有需要的Monoid实例并混入genericfunctions
模板。
import Monoid;
import std.stdio;
import std.conv;
mixin genericfunctions;
void main() {
writefln(to!string(TestMonoid(3)));
writefln(to!string(TestMonoid(3.3243)));
}
现在,您可以将int和double用作Monoid。
但是,当您拥有类似实例的Functor类型类时,事情就变得更加复杂了:
module Functors;
// generic Functor like generic Monoid
class Functor(alias T, A) {
pragma(msg,\"Not an instance of Functor\");
}
// very simple container to demonstrate functors behavior
class FunctorTest(A) {
public A a;
this(A a) {
this.a = a;
}
}
// instance of Functor for FunctorTest!A
class Functor(alias T:FunctorTest,A) {
static T!B fmap(B)(T!A a, B delegate(A) fn) {
return new T!B(fn(a.a));
}
}
一种算法如下所示:
template genericfunctions() {
T TestMonoid(T,N = Monoid!T)(T a) {
return N.mappend(N.mzero(),a);
}
// F is the Functor, A the functors type before,
// B the functors Type after, N is the instance of Functor
F!B fmap(alias F,A,B,N=Functor!(F,A))(F!A a, B delegate(A) fn) {
return N.fmap!B(a,fn);
}
}
幸运的是,使用时可以省略四个模板参数:
mixin genericfunctions;
void main() {
auto a = new FunctorTest!int(3);
auto b = fmap(a,(int b) {return b+ 0.5;});
writefln(to!string(b.a));
}
但是,当您要将另一个Functor实例用于Type时,必须指定fmap的所有4个type参数。有没有一种方法您只需要指定实例,就可以从中推导出其他参数?
有什么替代笨拙的mixin解决方法的方法吗?
我没有看到这种方法的其他缺点吗?
那其他方式呢?
感谢您阅读本文并抽出时间思考和回答:)
编辑:
是否可以使用D中的unittest来定义像函子定律这样的约束?那肯定很不错。
没有找到相关结果
已邀请:
3 个回复
邦绊门蔽惩
不需要:
这样就足够了。这样,也不需要9英镑。 是否可以定义约束 就像在单元测试中的函子定律 D吗 不能完全确定我了解您的要求,但是您可以使用模板函数/类来定义约束:
仅当
是整数类型时,此模板才会实例化。 请参阅“模板”页面底部的“模板约束”部分。
孤捷侩
盟犯涩沟都
这样,您可以创建一个模板约束,如下所示:
注意上面带有fmap的UFCS,fmap仍然与您的声明匹配。 另请注意,最好使用结构而不是类。由于它们是值类型,并且我们可以在D中包含编译时函数执行(CTFE),因此可以巧妙地使用opCall来使用它们,就好像它们是函数本身一样。