在我的库中,我有三种类型:
T
在以下条件下,这些类型类可以相互转换:
scala.math.Numeric
是AbelianGroup
类型,则它也是T
。AbelianGroup
是Monoid
,它也是AbelianGroup
(目前,Monoid
扩展T
,但不一定是这种情况)Monoid
是类型为U的向量,类型U是T
,则键入Monoid
也是AbelianGroup
。T
,则AbelianGroup
也是(Int, Int)
。例如,由于Int
是Vector over Int
,而(Int, Int)
是AbelianGroup,因此object Monoid {
implicit def fromAbelianGroup[T : AbelianGroup] : Monoid[T] = implicitly[AbelianGroup[T]]
implicit def fromVector[T : Vector[T, U], U : Monoid] : Monid[T] = ...
}
object AbelianGroup {
implicit def fromNumeric[T : Numeric] : AbelianGroup[T] = ...
implicit def fromOtherTypeX[T : ...] : AbelianGroup[T]
...
implicit def fromVector[T : Vector[T, U], U : AbelianGroup] : AbelianGroup[T] = ...
}
也是AbelianGroup。
这些关系和其他关系很容易在伴侣类中实现,如下所示:
(Int, Int)
这很好用,直到你尝试使用元组类型Monoid.fromAbelianGroup(AbelianGroup.fromVector(Vector.from2Tuple,
AbelianGroup.fromNumeric))
之类的东西作为Monoid。编译器找到两种方法来获得这种类型的Monoid类型类对象:
Monoid.fromVector(Vector.from2Tuple,
Monid.fromAbelianGroup(AbelianGroup.fromNumeric))
AbelianGroup
为解决这种歧义,我修改了Monoid伴随类,以包含从Numeric(以及可直接转换为/*revised*/
object Monoid {
//implicit def fromAbelianGroup[T : AbelianGroup] : Monoid[T] = implicitly[AbelianGroup[T]]
implicit def fromNumeric[T : Numeric] : Monoid[T] = ... //<-- redundant
implicit def fromOtherTypeX[T : ...] : AbelianGroup[T] = ... //<-- redundant
...
implicit def fromVector[T : Vector[T, U], U : Monoid] : Monid[T] = ...
}
object AbelianGroup {
implicit def fromNumeric[T : Numeric] : AbelianGroup[T] = ...
implicit def fromOtherTypeX[T : ...] : AbelianGroup[T] = ...
...
implicit def fromVector[T : Vector[T, U], U : AbelianGroup] : AbelianGroup[T] = ...
}
的其他类型)的直接转换。
AbelianGroup
然而,这有点令人不满意,因为它基本上违反了DRY委托人。当我为Numeric
添加新的实现时,我将不得不在两个伴随对象中实现转换,就像我为 #define O_WRONLY 01
#define O_APPEND 02000
int main(void)
{
// fd is an indentifier for the file that we are going to work with
int fd;
// We open the file with the write or append mode, so you will
// have to create the file testfile.txt in the current directory.
fd = open("jobby.txt", O_WRONLY|O_APPEND, 0);
if(fd < 0)
return 2;
char str[10]= "";
char buf1[] = "Please type username and hit Enter: ";
write(1, buf1, sizeof(buf1));
read (0, str, 10);
write(fd,str, sizeof(str));
char str1[10]= "";
char buf2[] = "Please type in a password and hit Enter: ";
write(1, buf2, sizeof(buf2));
read (0, str1, 10);
write(fd,str1, sizeof(str));
char str2[10]= "";
char buf4[] = "Please re-enter password and hit Enter: ";
write(1, buf4, sizeof(buf4));
read (0, str2, 10);
write(fd,str2, sizeof(str));
if(sizeof(str1)==sizeof(str2))
{
char buf5[] = "\n password match: ";
write(1, buf5, sizeof(buf5));
}
else
{
char buf6[] = "\n password mismatch: ";
write(1, buf6, sizeof(buf6));
}
和OtherTypeX等所做的那样。所以,我觉得我是&#39;在某个地方转了一圈。
有没有办法修改我的代码以避免这种冗余并解决编译时模糊错误?在这种情况下,最佳做法是什么?
答案 0 :(得分:0)
trait LowPriorityMonoidImplicits {
implicit def fromVector[T : Vector[T, U], U : Monoid] : Monoid[T] = ...
}
object Monoid extends LowPriorityMonoidImplicits {
implicit def fromAbelianGroup[T : AbelianGroup] : Monoid[T] = implicitly[AbelianGroup[T]]
}