2014-02-17 56 views
19

我試圖用我的方式理解Scala中的類型編程,並且我發現大多數關於類型編程需要知道的東西在編程中有一個類似的對應部分,如the type-level programming wiki page中所反映的。但是,我還沒有找到關鍵字或自我類型的類比。我懷疑也許期望這樣的事情沒有意義,但我想我會問。什麼是`this`關鍵字的Scala類型編程類比?

舉例來說,我可以寫出如下表示布爾值作爲運行時間值:

sealed trait BoolVal { 
    def not:BoolVal 
    def or(that:BoolVal):BoolVal 
    def and(that:BoolVal) = 
    (this.not or that.not).not 
    def imp(that:BoolVal) = 
    this.not or that 
} 
case object TrueVal extends BoolVal { 
    override val not = FalseVal 
    override def or(that:BoolVal) = TrueVal 
} 
case object FalseVal extends BoolVal { 
    override val not = TrueVal 
    override def or(that:BoolVal) = that 
} 

這裏我andimp能夠利用的事實,這並不重要,如果我是一個錯誤的對象或一個真正的對象被正確定義。我的TrueValFalseVal對象可以繼承相同的代碼。

我可以製作類似級別的編程結構,但我不明白如何在我的基本特徵中定義AndImp

sealed trait BoolType { 
    type Not <: BoolType 
    type Or[That <: BoolType] <: BoolType 
    type And[That <: BoolType] = ??? 
    type Imp[That <: BoolType] = ??? 
} 
sealed trait TrueType extends BoolType { 
    override type Not = FalseType 
    override type Or[That <: BoolType] = TrueType 
} 
sealed trait FalseType extends BoolType { 
    override type Not = TrueType 
    override type Or[That <: BoolType] = That 
} 

我可以看到它可能沒有意義,我的類型繼承類型,但肯定繼承抽象類型。有沒有在我的BoolType中定義AndImpl的方法,還是我必須在各自的TrueTypeFalseType特徵中定義每個?

回答

10

您可以隨時在你的布爾基本類型定義一個抽象類型如下:

trait MyBool extends BoolType{ 
    type This <: BoolType 
} 

trait TrueType extends BoolType{ 
    type This = TrueType 
} 

,你應該是好去與自己的參考。然後,你可以通過一個雙重否定使用德摩根定律做以下

!(x && y) == (!x || !y) 

然後你就可以得到你And條件去:

!(!x || !y) == !!(x && y) == (x && y) 
+2

DeMorgan's正是我所拍攝的像我的'BoolVal'特性。但是......我嘗試了你的建議,但它卻沒有編譯。特別是'And'和'Imp'的定義沒有編譯:'type And [That <:BoolType] = This.Not.Or [That.Not] .Not' and'type Imp [That <:BoolType ] = This.Not.Or [That]' – joescii

+0

不要使用'This.Not'我會嘗試使用This#Not'。你現在在類型層面工作。 – wheaties

+0

#FacePalm #MidnightPilotError #BeerThirty – joescii

9

我會建議使用self,您的博客後的調整。例如:

sealed trait BoolType { self => 
    type Not <: BoolType 
    type Or[That <: BoolType] <: BoolType 
    type And[That <: BoolType] = self.type#Not#Or[That#Not]#Not 
    type Imp[That <: BoolType] = self.type#Not#Or[That] 
} 
sealed trait TrueType extends BoolType { 
    override type Not = FalseType 
    override type Or[That <: BoolType] = TrueType 
} 
sealed trait FalseType extends BoolType { 
    override type Not = TrueType 
    override type Or[That <: BoolType] = That 
} 
+0

我喜歡這種方法,可以說不僅僅是創建一個'This'類型,因爲它可以防止漏出。我一定會把這個變化推向前進,並在後續的帖子中記錄下來。謝謝! – joescii

3

爲什麼不只是使用this關鍵字?當我自己探索類型級別的編程時,使用這個而不是自己時,我看不出有什麼區別。

sealed trait BoolType { 
    type Not <: BoolType 
    type Or[That <: BoolType] <: BoolType 
    type And[That <: BoolType] = this.type#Not#Or[That#Not]#Not 
    type Imp[That <: BoolType] = this.type#Not#Or[That] 
} 
+0

我同意你的意見。事實上,一旦我將我的短途旅行編入一篇文章,我選擇了這種確切的方法(沒有雙關語意思) – joescii

+1

我最近偶然發現了關於該主題的精彩博客系列。我將在本地聚會上介紹類型級編程。你的系列作爲一個例子。所以感謝偉大的工作! – mavilein

+0

太棒了!我希望這會順利!如果您需要任何額外幫助,請隨時與我聯繫。 – joescii

相關問題