2014-10-02 27 views
1

我試圖破譯這實際上意味着解碼scalacheck和scalatest代碼

check { (n: Int) => 
    n > 1 ==> n/2 > 0 
} 

http://www.scalatest.org/user_guide/writing_scalacheck_style_properties

我第一次試圖破譯該機構是否

((n: Int) => n > 1) ==> n/2 > 0 

or 

(n: Int) => (n > 1 ==> n/2 > 0) 

哪一個會它是?我猜測後者,因爲check方法需要一個函數,儘管方法'==>'也可能返回一個函數?

接下來,我看檢查方法簽名在https://searchcode.com/codesearch/view/12336175/

def check[A1,P](f: A1 => P) 
    (implicit 
    p: P => Prop, 
    a1: Arbitrary[A1], s1: Shrink[A1] 
) { 
    check(Prop.property(f)(p, a1, s1)) 
} 

我相信A1將是詮釋除非==>返回函數並改變返回值類型(可疑雖然我認爲)。我不知道如何在scalacheck庫中找到隱式函數P => Prop。

我注意到存在具有一個功能==>https://github.com/rickynils/scalacheck/blob/master/src/main/scala/org/scalacheck/Prop.scala

也許一個ExtendedBoolean(N> 1)被轉化爲一個ExtendedBoolean假設函數爲(N:強度)=>(N> 1 = => N/2> 0),然後我們得到

ExtendedBoolean(n > 1).==>(n/2 > 0) is called then. 

由於==實施>爲ExtendedBoolean是支柱(b)==> p,I最終與

Prop(n > 1) ==> (n/2 > 0) 

我真的很抱歉在這裏按照名稱調用進行融合,通常會捕獲這些值,除非此時n沒有值,因爲它最初是一個函數。無視我的困惑了一秒鐘,==的>爲支柱的實施因此

def ==>(p: => Prop): Prop = flatMap { r1 => 
    if(r1.proved) p map { r2 => mergeRes(r1,r2,r2.status) } 
    else if(!r1.success) Prop(r1.copy(status = Undecided)) 
    else p map { r2 => provedToTrue(mergeRes(r1,r2,r2.status)) } 
} 

所以,我們就像調用這個,所以我想用另一個隱含的版本在這裏道具

Prop(n > 1) ==> Prop(n/2 > 0) 

OK,和平面地圖是

Prop(prms => f(this(prms))(prms)) 

嗯,必須有另一個轉換到道具。我開始跟蹤PRMS,然後看對象PROP申請布爾方法,該方法是

def apply(b: Boolean): Prop = if(b) proved else falsified 

,但我解決不了b鍵真的還是假的,因爲這些功能尚未評估。這一切如何協同工作?我想我幾乎沒有想到這裏的一些概念。有人可以解釋這個好一點嗎?

+0

你不會錯過任何東西。 ExtendedBoolean通過名稱參數[def ==>(p:=> Prop)= Prop(b)==> p](https:// github。COM/rickynils/scalacheck /斑點/主/ SRC /主/階/組織/ scalacheck/Prop.scala#L318)。 「通過名稱參數不在函數應用程序的位置進行評估,而是在函數內的每次使用時進行評估,也就是說,參數是使用按名稱進行評估的。」 – Jamil 2014-10-02 17:53:33

+0

我習慣像log4scala這樣的地方log.debug(=>字符串)採取像log.debug(「你好」+名稱)和名稱已定義的名稱。在這種情況下,按名稱正在接收名稱尚未定義的內容。這甚至有可能嗎?在log.debug的情況下,它會捕獲關閉中的name的值,以防以後對關閉進行評估(當然也可能不會),但我沒有在上面的代碼中獲取它。 – 2014-10-02 18:07:17

回答

0

你的是一個真正的ScalaCheck問題,但要避免整個問題的一種方法是使用ScalaTest的PropertyChecks語法而不是ScalaCheck的(這是在ScalaTest由跳棋支持):

import org.scalatest.prop.Checkers._ 

check { (n: Int) => 
    n > 1 ==> n/2 > 0 
} 

變爲:

import org.scalatest.MustMatchers._ 
import org.scalatest.prop.PropertyChecks._ 

forAll { (n: Int) => 
    whenever (n > 1) { 
    n/2 must be > 0 
    } 
} 
+0

謝謝你的回答,但我不想回避這個問題。我正在努力增加我對Scala的知識。我習慣像log.debug(=> String),我可以傳入「我的名字是」+名稱和名稱被捕獲爲「院長」或其他東西。在上面的scalacheck例子中,n沒有價值。你真的可以將一個函數分割成一個閉包,可能會像後面那樣評估它嗎?或者我可能會誤解代碼。 – 2014-10-02 18:08:55