0

私はHaskellを学んでいます。この質問は非常にばかげているかもしれませんが、申し訳ありませんが答えがわかりません

リストの 4 タプルを取る関数があります。これらのリストのサイズは異なる可能性がありますが、タプルでは同じサイズです

foo ([a],[b],[c],[d]) = concat [[a],[b])

たとえば、そのサイズよりも大きいリストでは機能しません

foo ([1],[2],[3],[4]) // works fine 
foo ([1,2] , [2,3] , [3,4] , [5,7]) or any larger size of those list generate error

それを一般化するためのヒントはありますか?

4

2 に答える 2

1

ソース コードのテキスト[1]が値である単一の要素を持つリストを意味するのと1同じように、ソース コードのテキスト[a]は、変数a1である単一の要素を持つリストを意味します。これは任意のサイズのリストを意味するものではなくa、リストではなくリストの単一の要素を指します。

方程式の左辺には、[a]正確に 1 つの要素 (0 ではなく、2 つまたは 3 つ以上ではない) を含むリストのみに一致するパターンがあります。aその単一要素の値は、式の右側で参照できます。

したがって、このコード:

foo ([a],[b],[c],[d]) = concat [[a],[b]]

foo4 つのシングルトン リストのタプルに適用した結果の定義を示します。最初の 2 つのリスト ( および )の 1 つの要素を取得し、それらを新しいシングルトン リスト ( および ) にラップし、aそれら2 つのリストを別のリストに入れてリストのリスト ( ) を作成し、そのリストを関数に渡します ( )。b[a][b][[a],[b]]concat [[a],[b]]

リストのいずれかが複数の要素を持っているか、空の場合、この方程式は結果が何であるかを示しませんfoo。関数 を定義するのに役立つ方程式が他にない場合、そのような非準拠の入力fooを呼び出すと、パターン マッチ エラーが発生します。foo

(私が推測するように) この定義が任意の4 つのリストのタプルに適用されると言いたい場合は、次のように記述します。

foo (a,b,c,d) = concat [a,b]

a、、、およびをb囲む角括弧がないことに注意してください。このバージョンでは、最初の 2 つのリスト (および) の全体を取得し、それらを別のリストに入れてリストのリストを作成し ( )、そのリストを関数に渡します ( )。cdab[a,b]concat [a,b]

関数の(コードから推測されたものか、宣言されたものかに関係なく) は、foo引数として受け取るタプル内のものはリスト2であることを示しています。リストであるすべての変数を角括弧で囲む必要はありません。可能なリストと照合したい場合は、a;と書くだけです。リスト[a]は正確に 1 つの要素のリストでなければaならず、変数によって自由に一致するのはその要素のみであり、リスト自体ではありません。

角かっこの構文を使用するときはいつでも、固定数の要素 ( 3 )を持つリストを作成していることになり、角かっこ内のものはリストの個々の要素です。


1[a]が値式であるコンテキスト。これが型式で発生する場合、要素が type であるリスト[a]です a

2c技術的には、ここで推論された型を使用している場合、提案されたバージョンではおよびの型を制約するものはまったくありdません。それらは使用されていないため、リストである必要はありません。

3リスト内包表記 (例: [x + 1 | x <- [1, 2, 3]]) または数値範囲式 (例: [1..n]) を記述している場合を除きます。

于 2013-10-14T07:15:29.450 に答える
0

これはうまくいくはずです:

foo (a:_,b:_,c:_,d:_)= concat [[a],[b]]

上記の関数では、各リストのパラメーターの最初の要素をパターン マッチするだけです。

はるかに単純なコード:

foo (a:_,b:_,_,_)= [a, b]

ghci で:

ghci> foo ([1],[2],[3],[4])
[1,2]
ghci> foo ([1,2] , [2,3] , [3,4] , [5,7])
[1,2]
于 2013-10-14T05:52:58.243 に答える