3

この関数が ":" では機能しないのに、|| では機能する理由について質問があります。また、「:」が || に置き換えられる理由 なぜ書き込めないのかというと

xs (y:ys) を含む = プレフィックス xs (y:ys) : xs ys を含む

 contains :: String -> String -> Bool
 contains [] _ = True
 contains _ [] = False
 contains xs (y:ys) = prefix xs (y:ys) || contains xs ys
4

1 に答える 1

9

重要なアイデア

:リストの回答を作成するため、||または&&真/偽の回答を作成するため、+または*数値の回答を作成するために使用します。何を組み合わせているかを考えてください。常にそうである必要はありません:

詳細

なぜ書けないのか聞いてみようと思います

contains xs (y:ys) = prefix xs (y:ys)  :  contains xs ys

:リストの先頭に要素を接着するためのものであるため、タイプはa -> [a] -> [a]です。これは、左側に1つ、右側にリストを配置することを意味します。再帰関数を書くときによく使用します。たとえば、次のように定義できます。

increase :: [Int] -> [Int]
increase [] = []
increase (x:xs) = x + 5 : increase xs

これx + 5Intincrease xsです[Int]

あなたの関数を見てみましょう。そのタイプはcontains :: String -> String -> Bool、文字列、次に文字列を取り、次にブール値を与えるようになっています。=あなたが得た直後prefix xs (y:ys)。今prefixは同じタイプです:prefix :: String -> String -> Bool、それで今私たちはそれを与えましたxs、そして(y:ys)それは私たちにブールを与えています。

行の最後にはcontains xs ysBoolもあります。そのため、それらの間に置く:と、次のようなものになります。

False : True

Trueただし、はリストではないため、これを行うことは許可されていません。(覚えておいてください(:) :: a -> [a] -> [a]。)あなたはできるFalse:[True](そうなるでしょうが[False,True]、とにかくそれはあなたが望むことではありません。

そこにあるかどうかを確認する必要xsがあります-前(y:ys) または後で。またはの記号はです||。したがって、コードは

xsそれが(y:ys)その前にある場合( )またはそれが( )prefix xs (y:ys)のどこかにある場合にあります。yscontains xs ys

(前に:置く記号)が含まれていると、

xsそれがその前にある(y:ys)場合は(prefix xs (y:ys))にあり、その答えをこれらの答えの前に置きます-それはyscontains xs ys)のどこかにあります。

これは意味がありません。||そのため、( )の前ではなく()が必要です:

于 2012-10-25T23:18:20.937 に答える