0

リスト内の要素のペアがリスト内の唯一のペアであり、同一の連続する要素が3つ以下であると想定して、リスト内の要素のペアを検索しようとしています。

リストを取り込んで、ペアの最初の要素がある場合はそのインデックスを返す関数があります。そうでない場合は、-1を返します

searchForPairs xs = searchHelp xs ((genericLength xs) - 1)
    where searchHelp xs n
        | searchHelp xs 0 = -1              -- no pairs found
        | (xs !! n) == (xs !! (n - 1)) = n
        | otherwise = searchHelp xs n-1

何らかの理由で、次のエラーが返されます。

Couldn't match expected type `Bool' with actual type `Int'
In the expression: n
In an equation for `searchHelp':
    searchHelp xs n
      | searchHelp xs 0 = - 1
      | (xs !! n) == (xs !! (n - 1)) = n
      | otherwise = searchHelp xs n - 1
In an equation for `searchForPairs':
    searchForPairs xs
      = searchHelp xs ((genericLength xs) - 1)
      where
          searchHelp xs n
            | searchHelp xs 0 = - 1
            | (xs !! n) == (xs !! (n - 1)) = n
            | otherwise = searchHelp xs n - 1

うまくいくようです。なぜそうではないのか、何か考えはありますか?

4

4 に答える 4

2

私はあなたがやりたいことを完全に理解することはできませんでしたが、コードから、あなたがリスト内で等しい2つの連続した要素を見つけようとしているように見えます。を使用してリストにインデックスを付ける代わりに、!!パターンマッチングを使用して、リストの最初の2つの要素を抽出し、それらが等しいかどうかを確認し、等しくない場合は残り(2番目の要素を含む)を検索し続けることができます。リストに少なくとも2つの要素が含まれていない場合は、Nothing

searchForPairs xs = go 0 xs where
  go i (x1:xs@(x2:_)) | x1 == x2 = Just i
                      | otherwise = go (i+1) xs
  go _ _ = Nothing
于 2012-10-08T04:49:22.083 に答える
2

2 つの問題があります。最初の行は次のとおりです。

        | otherwise = searchHelp xs n-1

コンパイラは、意図したようにこれを(searchHelp xs n) - 1ではなくとして解釈します。searchHelp xs (n-1)2 番目の問題は、ガードの使用にあります。

        | searchHelp xs 0 = -1              -- no pairs found

はブール式ではないためsearchHelp xs 0(パターンとして使用したかったため)、コンパイラはそれを拒否しました。2 つの簡単な解決策を確認できます。

searchForPairs xs = searchHelp xs ((genericLength xs) - 1)
    where searchHelp xs n
        | n == 0 = -1              -- no pairs found
        | (xs !! n) == (xs !! (n - 1)) = n
        | otherwise = searchHelp xs (n-1)

searchForPairs xs = searchHelp xs ((genericLength xs) - 1)
    where
      searchHelp xs 0 = -1         -- no pairs found
      searchHelp xs n
        | (xs !! n) == (xs !! (n - 1)) = n
        | otherwise = searchHelp xs (n-1)

残念ながら、これは機能しますが、非常に非効率的です。これは、 を使用しているためです!!。Haskell では、リストはリンクされたリストであるためxs !! n、1 ではなく n ステップを使用します。これは、関数にかかる時間がリストの長さの 2 次であることを意味します。これを修正するには、パターン マッチングを使用してリストを順方向にループします。

searchForPairs xs = searchHelp xs 0 where
    searchHelp (x1 : x2 : xs) pos
        | x1 == x2 = pos
        | otherwise = searchHelp (x2 : xs) (pos + 1)
    searchHelp _ _ = -1
于 2012-10-07T23:34:06.747 に答える
2

@gereeter はすでにエラーについて説明していますが、答えが見つからない場合は戻ってはならないことを指摘したいと思います。代わりに、答えがなく、答えがの場合-1は戻る必要があります。これにより、多くの種類のエラーから保護されます。NothingJust pospos

于 2012-10-08T03:51:49.380 に答える