Type safe method chaining that doesn't allow repeats of operations

前端 未结 2 1543
忘了有多久
忘了有多久 2020-12-10 17:38

I want to implement method chaining like in those questions:

Best practice to implement Scala trait which supports method chaining ;

Scala DSL: method chaini

相关标签:
2条回答
  • 2020-12-10 17:47

    See Phantom Types In Haskell and Scala by 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]
    }
    

    to be used like this

    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
                                    ^
    
    0 讨论(0)
  • 2020-12-10 17:57

    here you can ifnd an improved solution :

    http://jim-mcbeath.blogspot.fr/2009/09/type-safe-builder-in-scala-part-3.html

    (which actually relies on the phantom types)

    0 讨论(0)
提交回复
热议问题