我使用无形的Poly1
来构建案例类的方案(描述它们的序列化)。构建Schema
case class A(b: B, c: String, d: List[Int], e: Option[List[Option[Int]]])
每个包含的类型都需要一个模式。
Schema
对象(除了其他内容)保存其成员的示例值。我从实例中为所有原语类型(Int
,Float
,String
,...)提取这些示例值,其方案由动态构建我的Poly1
。所有复杂类型(我的意思是指具有其他成员值的自定义类型)都会被引用,因为它们也可能具有自定义序列化方法。通过要求在隐式范围中存在模式,可以很容易地解决这个问题。
现在知道如何为任何列表(或任何其他集合)构建Schema
iff 类型参数有Schema
。对于像Option
这样的其他monad类型也是如此。
Poly1
的想法是将成员类型映射到他们的方案,这些方案可以动态构建,也可以从隐式范围中查找。这需要我为所有原始类型以及所有必需的monad定义一个案例。这种方法通常有效,但有很多样板。
当前Poly1
对象(NGSchema
是trait
所有Schema[T]
个实例都会继承,ref[T]
会从Schema[T]
查找integer
个实例隐式范围和函数long
,float
和Schema[T]
使用给定示例构造private object typeRecursion extends Poly1 {
implicit val caseInt = at[Int] [NGSchema](integer(_))
implicit val caseLong = at[Long] [NGSchema](long(_))
implicit val caseFloat = at[Float] [NGSchema](float(_))
...
implicit def caseOption[T: Schema](implicit c: Case.Aux[T, NGSchema]) = at[Option[T]][NGSchema]{
case Some(v) => OptionSchema(typeRecursion(v)(c))
case None => OptionSchema(ref[T])
}
implicit def caseList[T: Schema](implicit c: Case.Aux[T, NGSchema]) = at[List[T]][NGSchema]{
case v :: tl => SeqSchema(typeRecursion(v)(c))
case Nil => SeqSchema(ref[T])
}
...
implicit def caseElse[T: Schema] = at[T][NGSchema]{
case _ => ref[T]
}
}
:
e
但是在成员Option[List[Option[Int]]]
的情况下,这会失败,因为Poly1
的模式将不会出现在隐式作用域中,因为它应该在运行中构建。我相信我的Option
应该是递归的,以便很好地解决这个问题。然而,这会产生这样的问题:Option[List[Option[Int]]]
情况确实需要某种类型绑定用于内部最多类型,这在递归中的那个点是未知的 iff 这是一个复杂类型,因为这个不能在飞行中构建。
我希望功能会将OptionSchema(SeqSchema(OptionSchema(integer(example))
映射到Option[B]
,而Schema[B]
应该从隐式范围查找OptionSchema(ref[B])
并执行// for example: language = @"en" and region = @"UK"
NSString* languageDescription = [NSString stringWithFormat:@"%@-%@",language,region]
[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects: languageDescription, nil]
forKey: @"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize]; //to make the change immediate
。
这是解决问题的正确方法吗?
答案 0 :(得分:1)
Poly1
本身不是implicit
,只有案例是隐含的。我认为你混淆了类型类级别和价值级别。我会将隐式Schema
实例的提供与实际操作它们的函数(可能只是普通函数?)分开:
implicit object IntSchema extends NGSchema[Int]{ ... }
implicit def optionSchema[T: Schema] = new Schema[Option[T]]{...}
...
def myFunction[T: Schema](t: T) = ... //or Poly with cases here if you need it.