2014-02-21 139 views
1

我試圖讓一個列表理解工作,其目的是驗證每個元素XList後面跟着X+Incr(或一個空列表)。稍後,我將使用該列表並將其與使用lists:seq(From,To,Incr)生成的列表進行比較。 目的是練習編寫測試用例和查找測試屬性。Erlang列表理解,再次

我已經做了以下步驟:

1> List. 
[1,3,5,8,9,11,13] 
2> Incr. 
2 
3> List2=[X || X <- List, (tl(List) == []) orelse (hd(tl(List)) == X + Incr)]. 
[1] 

對我來說,這似乎是我的列表中理解只需要第一個元素在List,運行通過過濾器/警衛,並停止,但應對List中的每個元素都做同樣的事,對吧?

我想第3行返回一個列表,如下所示:[1,2,9,11,13]

任何想法如何修改當前的理解,或完全改變我的方法?

PS。我正在使用eqc-quickcheck,通過Quviq's webpage發佈,如果這可能會改變如何解決這個問題。

回答

2

的問題,您的列表理解的是,List總是指整個列表。因此,該條件只允許那些X是等於List減去Incr第二元件:

(hd(tl(List)) == X + Incr) 

第二個元素是永遠3,所以這個條件僅持有對於X = 1

列表解析無法「向前看」,以其他列表元素,所以這或許應該被寫爲遞歸函數:

check_incr([], _Incr) -> 
    true; 
check_incr([_], _Incr) -> 
    true; 
check_incr([A, B | Rest], Incr) -> 
    A + Incr == B andalso check_incr([B | Rest], Incr). 
+0

是的......當然。愚蠢的我(;我想理解不是正確的工具,就像AndréLaszlo說的那樣... –

+0

我會實現一個輔助函數,而不是像上面的評論提及的那樣,假設這將是最簡單的方法! –

1

也許我誤解了你,但列表理解應該是"creating a list based on existing lists"。這裏是生成您的列表中選擇一個方式使用列表理解不使用lists:seq

> Start = 1, Inc = 2, N = 6. 
6 
> [Start + X*Inc || X <- lists:seq(0,N)]. 
[1,3,5,7,9,11,13] 
+0

是的,生成列表不是問題。問題是要檢查List是否滿足每個元素X的標準,下一個元素是X + Incr還是一個空列表。 –

+0

然後,也許列表理解是工作的錯誤工具,因爲你無法查看相鄰的元素? –

+0

我認爲你是對的......理解不是正確的工具! –

0

你可以做這樣的事情:

> lists:zipwith(fun (X, Y) -> Y - X end, [0 | List], List ++ [0]). 
[1,2,2,2,2,2,2,-13] 

然後檢查所有元素都等於Incr,除了第一,應該是等於From和最後那個應該比-To大於或等於。

0

一個快速的評論是,值List確實不是改變時,在理解評估時,它總是指初始列表。它是X,它遍歷列表中的所有元素。這意味着您的測試將始終引用列表的第一個元素。由於列表理解一次提供了列表元素,因此當您想要比較列表中的元素時,它通常不是一個好工具。

列表理解無法查看連續的子列表,這是您需要的(如Common Lisp中的MAPLIST)。