1

haskellのリストの最初と最後の要素を交換しようとしています。パターンの一致、式、関数などを試しました。これが最後の試みです。

cambio xs = [ cabeza++([x]++cola)|x<-xs, cabeza <- init x, cola <- last x, drop 1 x, drop 0 ([init x])]

私のコンパイラは次のエラーをスローします:

Couldn't match expected type `Bool' with actual type `[a0]'
    In the return type of a call of `drop'
    In the expression: drop 1 x
    In a stmt of a list comprehension: drop 1 x

誰か助けてもらえますか?私はこれを2日間試みました

4

3 に答える 3

4

ここにいくつかのヒントがあります:

  1. リスト内包でこれを解決することはできません。
  2. 基本的な(些細な)ケースを特定します-空のリストと1つの要素のリスト。それらのケースをカバーする方程式を書いてください。
  3. 他のすべての場合、入力リストの長さは2以上になります。必要なリストは次のとおりです。

    [z] ++ xs ++ [a]

ここで、zは最後の要素、入力リストの最初の要素、xsは入力の中央部分です。

ここで、入力文字列の長さがkの場合、xsの長さを教えてください(または自分自身)。

  1. 複数の要素を持つリストの場合をカバーする方程式を書いてください。ヘッド、ラスト、レングス、ドロップ、テイクなどの機能を使用できます。
于 2013-03-17T23:44:18.070 に答える
2

リストはこれを行うための最良のデータ構造ではないと思いますが、ここでは次のようになります。

swap list = last list : (init . tail $ list) ++ [head list]

これにはリストをトラバースする必要があり、長いリストでは遅くなります。これがリンクリストの性質です。


質問者からのベースケースで更新:

swap [] = [] 
swap [a] = [a] 
swap list = last list : (init . tail $ list) ++ [head list] 
于 2013-03-17T23:43:38.260 に答える
2

これは、特に標準のリスト関数を使用すると、かなり簡単に実行できます。

swapfl [] = []
swapfl [x] = [x]
swapfl (x:xs) = (last xs : init xs) ++ [x]

またはそれらなしで(これは読みにくく、通常は行われず、推奨されませんが):

swapfl' [] = []
swapfl' [x] = [x]
swapfl' (x:xs) = let (f, g) = sw x xs in f:g
  where sw k [y] = (y, [k])
        sw k (y:ys) = let (n, m) = sw k ys in (n, y:m)

または他の多くの方法の1つ。

それがお役に立てば幸いです...私はあまり説明していませんでしたが、率直に言って、リスト内包表記を完全に誤解しているように見えるため、この関数に関する限り、問題があったことを正確に伝えることは困難です。代わりにそれらを説明するのが最も有益かもしれないと思いますか?

そして、なぜこれはリスト内包で解決できないのでしょうか?機能のようでしたが、形が違うのは大変でした

あまり。リスト内包表記は、リストを簡単に定義するのに役立ち、数学の集合の内包的表記法と非常に密接に関連しています。これは、この特定のアプリケーションには役立ちません。リストの要素を変更することは非常に得意ですが、内包表記はリストを並べ替えるのにあまり得意ではないためです。

理解には、リスト内の要素の定義、1つ以上の入力リスト、および0個以上の述語の3つの部分があります。

[ definition | x <- input1, y <- input2, predicate1, predicate2 ]

定義は、入力の矢印が指している変数(この場合はxとy)の観点から、作成しているリストの1つの要素を記述します。各入力には、矢印の右側にリストがあり、左側に変数があります。私たちが作成しているリストの各要素は、入力リストからそれらの変数に要素の各組み合わせを抽出し、それらの値を使用して定義部分を評価することによって構築されます。例えば:

[ x + y | x <- [1, 3], y <- [2, 4] ]

これにより、以下が生成されます。

[1 + 2, 1 + 4, 3 + 2, 3 + 4] == [3, 5, 5, 7]

また、フィルターのような述語を含めることもできます。各述語は、入力要素に関して定義されたブール式であり、新しいリスト要素がである場合は常に評価されます。述語のいずれかがfalseであることが判明した場合、それらの要素は作成中のリストに含まれません。

あなたのコードを見てみましょう:

cambio xs = [ cabeza++([x]++cola) | x<-xs, cabeza <- init x, cola <- last x,
                                    drop 1 x, drop 0 ([init x])]

この理解のための入力は、、、x <- xsおよびcabeza <- init xですcola <- last x。最初の要素は、のすべての要素xsが新しいリストの要素を定義するために使用され、各要素に名前が付けられることを意味しますxinitlastはタイプであるため、他の2つは意味がありません[a] -> aが、矢印の右側にあるためリストであるx必要があり、矢印の左側にあるためリストの要素である必要があります。これをコンパイルするためには、xsはtype[[[a]]]である必要がありますが、これはあなたが望むものではないと確信しています。

drop 1 x使用した述語はとですdrop 0 [init x]。リストの最初の要素を削除して、最初の要素で何をしようとしていたかは理解できますがx、これはリスト自体ではなく、リストの要素にすぎないため、機能しません。2つ目は、drop 0「次のリストの先頭からゼロ要素を削除する」ことを意味しますが、これはまったく何もしません。いずれの場合も、述語はブール値である必要があるため、そのようなものを述語に入れることは機能しません。これが、コンパイラエラーが発生した理由です。次に例を示します。

pos xs = [ x | x <- xs, x >= 0 ]

この関数は、数値のリストを取得し、すべての負の数値を削除して、結果を返します。述語はx >= 0、ブール式である、です。式がfalseと評価された場合、評価されている要素は結果のリストから除外されます。

使用した要素定義はですcabeza ++ [x] ++ cola。これは、「結果のリストの各要素自体がリストであり、リスト内のすべての要素、cabezaを含む単一の要素、xリスト内のすべての要素で構成されている」ことを意味します。colaこれは、あなたが行っていたものとは逆のようです。にとって。パイプ文字の前の部分は、リスト自体ではなく、単一の要素を定義することに注意してください。また、変数を角かっこで囲むと、その変数とその変数のみを含む新しいリストが作成されることに注意してください。と言う場合y = [x]、これはyに単一の要素xが含まれていることを意味し、xがリストであるかどうかについては何も言いません。

それがいくつかのことを解決するのに役立つことを願っています。

于 2013-03-18T02:39:17.343 に答える