2017-08-19 9 views
1

私はハスケルにとって非常に新しく、代数的グループでいくつかのことをしようとしています。私の最初の機能は、操作とセットを受け取り、同じセットのメンバーのペアでその操作を実行することによって生成できるセットのすべてのメンバーを見つけることです。これは、このために私のコードです:ハスケルリストの理解述語の順序

group' f xs = [a | a <- xs, a <- combSet] 
    where combSet = [f x y | x <- xs, y <- xs] 

しかし、このコードは、単にa <- xs述語を無視し、combSetのメンバーのセットを返します。

*Main> group' (*) [1, 2, 3, 4, 5] 
[1,2,3,4,5,2,4,6,8,10,3,6,9,12,15,4,8,12,16,20,5,10,15,20,25,1,2,3,4,5,2,4,6,8,10,3,6,9,12,15,4,8,12,16,20,5,10,15,20,25,1,2,3,4,5,2,4,6,8,10,3,6,9,12,15,4,8,12,16,20,5,10,15,20,25,1,2,3,4,5,2,4,6,8,10,3,6,9,12,15,4,8,12,16,20,5,10,15,20,25,1,2,3,4,5,2,4,6,8,10,3,6,9,12,15,4,8,12,16,20,5,10,15,20,25] 

をしかし、私は理解述語の順序を切り替えたときに、

group' f xs = [a | a <- combSet, a <- xs] 
    where combSet = [f x y | x <- xs, y <- xs] 

には、正しい値を返しますが、リストが予想以上に道大きいです:

*Main> group' (*) [1, 2, 3, 4, 5] 
[1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5] 

誰が私にこのようなことが起こったのか、私が何か愚かなことをしたことを教えてもらえますか?

答えて

5

最初に述語がありません。 xscombSetの2つのリストがあります。だから、私たちは単純な例を用いて動作をチェックしてみましょう:

example = [a | a <- [1,2,3], a <- [4,5,6]] 

これは、concat $ replicate 3 [4,5,6]にすなわち[4,5,6,4,5,6,4,5,6]をリードします。最初のリストの要素がないことに注意してください。後でバインドするaシャドウ

"リスト[1,2,3]のすべての要素に対して、現在の要素aの名前を付けてから、リストのすべての要素を指定してください。[4,5,6]:リストの現在の要素も同じ名前です)を返して、a s "を返します。

上記のコードは

example = [a | _ <- [1,2,3], a <- [4,5,6]] 

または任意の他の名前の代わりに_することと等価です。

述語の場合は、Bool式が必要です。

evenNumbers = [a | a <- [1..100], even a] 

あなたの場合、ブール式はおそらくa `elem` combSetです。

+0

ああ、説明をありがとう。私は数学的なバックグラウンドを持ち、思考リストの解説はセットの定義と同じでした。 – user2461616

3

[a | a <- xs, a <- combSet]は、最初のaが2番目のものによって「シャドーイング」されているため、[a | x <- xs, a <- combSet]に相当します。これは、同じ識別子のネストされた再定義がある場合に常に発生します。 \a -> ... (\a -> ....)

-Wallで警告をオンにすると、この問題が発生するはずです。

代わりに[a | a <- xs, elem a combSet]を使用して、がcombSetの内部で発生することを確認できます。

関連する問題