2017-02-25 16 views
3

我有以下特性:ScalaCheck無法施展布爾扶植例如

import org.scalacheck.Prop.propBoolean 

def elementsAreReversed(list: List[Int], reversed: List[Int]): Boolean = 
    if (list.isEmpty) true else { 
    val lastIdx = list.size - 1 
    list.zipWithIndex.forall { case (element, index) => 
     element == reversed(lastIdx - index) 
    } 
    } 

val propReversed = Prop.forAll { list: List[Int] => 
    val reversed = list.reverse 

    if (list.isEmpty) 
    list == reversed 
    else { 
    val hasSameSize = reversed.size == list.size 
    val hasAllElements = list.forall(reversed.contains) 

    // It works until I add a label here: 
    hasSameSize && hasAllElements && elementsAreReversed(list, reversed) 
    } 

如果添加一個標籤它打破:

hasSameSize :| " a label which doesn't let the code compile" && 
    hasAllElements && 
    elementsAreReversed(list, reversed) 

編譯器給了我下面的:

錯誤:(47,36)從Any => org.scalacheck.P​​rop中沒有隱式視圖可用。 VAL propReversed = Prop.forAll {列表:列表[INT] =>

錯誤:(47,36)不夠論據方法FORALL:

(隱式號碼:任何=> org.scalacheck.P​​rop隱式A1:org.scalacheck.Arbitrary [列表[INT]],隱式S1:org.scalacheck.Shrink [列表[INT]],隱PP1:列表[INT] => org.scalacheck.util.Pretty)的有機.scalacheck.P​​rop。未指定的值參數 P,A1,S1 ...

VAL propReversed = {Prop.forAll列表:列出[INT] =>

我使用ScalaCheck版本1.13.4

回答

4

的問題是,你有一個if表達有型Boolean且類型Prop假側真實的一面。編譯器將應用propBoolean隱式轉換的情況下一個布爾值,它需要一個Prop,但有條件這樣是不是那些地方,而不是簡單的編譯器將需要至少上限的BooleanProp之一,並使得該返回類型。 (也許有一點更令人驚訝的,這是真的,即使Prop至上和Boolean秒。)

有幾種方法,你可以做這項工作,但最簡單的就是運用明確的轉換:

val propReversed = Prop.forAll { list: List[Int] => 
    val reversed = list.reverse 

    if (list.isEmpty) Prop.propBoolean(list == reversed) else { 
    val hasSameSize = reversed.size == list.size 
    val hasAllElements = list.forall(reversed.contains) 

    hasSameSize :| " a label which doesn't let the code compile" && 
     hasAllElements && elementsAreReversed(list, reversed) 
    } 
} 

對我來說這是看中了隱式轉換,支持DSL的挫折只是另一個例子。我喜歡ScalaCheck,每天使用它,但我實在不明白在做後空翻的價值支持時的招數只是要打破一旦他們開始用Scala的(非常複雜)語法的其他角落互動稍微更簡潔的使用。

相關問題