不允许重复操作的类型安全方法链 [英] Type safe method chaining that doesn't allow repeats of operations

查看:39
本文介绍了不允许重复操作的类型安全方法链的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想像在这些问题中那样实现方法链:

I want to implement method chaining like in those questions:

实现支持方法的Scala trait的最佳实践链接 ;

Scala DSL:方法链与无参数方法

但是,我希望一旦使用了属性",就不能再使用它.例如,假设我有一个类Myclass",我想允许最多使用一次定义foo"和定义bar",我不关心最终的返回类型.因此:

However, I want that once a "property" has been used, it cannot be used anymore. For example lets assume that I have a class "Myclass" for which I want to allow the use of definition "foo" and definition "bar" at most once and I don't care about the final return type. Thus:

val c = new Myclass
c foo //ok !
c foo bar // ok!
c foo foo // refuse to compile
c foo bar foo //refuse to compile

我在这个问题上挣扎了一段时间,我的视力开始变得模糊!我尝试使用隐式类,但是,他们是否需要解析没有使用关联属性的对象,我找不到如何,他们是否需要通过删除它来消耗"该属性从对象可用属性中,再次,我找不到方法.

I'm struggling with this problem for a while and my vision starts becoming fuzzy! I tried to use implicit classes, however, whether they need to parse objects that has not used the associated property, and I can't find how, whether they need to "consume" the property by removing it from the object available property, and, again, I can't find how.

我目前在反射 API 中搜索,但对我来说仍然有点模糊.

I'm currently searching in the reflection API, but it is still a little obscure for me.

帮助将不胜感激!=)

推荐答案

参见 Haskell 和 Scala 中的幻影类型,作者 James Iry.

您也可以使用类型安全的构建器模式:

You could also use type-safe builder pattern:

trait TTrue
trait TFalse

@annotation.implicitNotFound(msg = "Cannot call same method twice.")
sealed abstract class =^=[From, To]
object =^= {
  private val singleton_=^= = new =^=[Any, Any]{}
  implicit def tpEquals[A]: A =^= A = singleton_=^=.asInstanceOf[A =^= A]
}

class Myclass[TFoo, TBar, TBuz] private(){
  def foo(implicit e: TFoo =^= TFalse) = new Myclass[TTrue, TBar, TBuz]
  def bar(implicit e: TBar =^= TFalse) = new Myclass[TFoo, TTrue, TBuz]
  def buz(implicit e: TBuz =^= TFalse) = new Myclass[TFoo, TBar, TTrue]
}

object Myclass{
  def apply() = new Myclass[TFalse, TFalse, TFalse]
}

像这样使用

scala> Myclass().foo.bar.buz
res0: Myclass[TTrue,TTrue,TTrue] = Myclass@12ac706a

scala> Myclass().bar.buz.foo
res1: Myclass[TTrue,TTrue,TTrue] = Myclass@1e69dff6

scala> Myclass().foo.buz.foo
<console>:12: error: Cannot call same method twice.
              Myclass().foo.buz.foo
                                ^

这篇关于不允许重复操作的类型安全方法链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆