2

文字列のリスト内の文字列で文字が既に使用されているかどうかを確認しようとしています。はいの場合 - 比較する次の文字を選択します。「いいえ」の場合 - このレターを返送し、最初のリストを更新します。

私が使用しているリストをチェックインするには:

check:: [String] -> Char -> Char
check s c 
    | any (elem c) s = check s (next c)
    | otherwise = do update s c 
                     return c

しかし、それは私にエラーを与えます:

タイプ '[Char]' と 'Char' を一致させることができませんでした
予期されるタイプ: [String] -> [Char] -> Char
実際のタイプ: [String] -> [Char] -> [Char]
' の stmt 内do' ブロック: sc を更新

私の更新機能には次の宣言があります:

update:: [String] -> Char -> [String]

ガードで2つのアクションを実行する正しい方法はありますotherwiseか? cと更新されたs の両方をパラメーターとして取る別の再帰関数で使用するには、cを返す必要があります。Char [String]

リストを更新せずにcのみを返すこの関数を使用すると、エラーは発生しません。

check:: [String] -> Char -> Char
check s c 
    | any (elem c) s = check s (next c)
    | otherwise = c

どんなヒントでも大歓迎です。

更新:私の次の機能は:

next :: Char -> Char
next 'Z' = 'A'
next c = chr (ord c + 1)

そして更新のために私が試した:

update:: [String] -> Char -> [String]
update s c = s ++ [[c]]

問題は、後で更新の結果である which をc[String] (チェックの結果)と一緒に別の関数に使用する必要があることです。そのため、チェックを実行した後、値を返し、それでリストを更新する必要があります。Char

4

1 に答える 1

1

Haskell は関数型言語であるため、データ構造を変更することを考えることはできません (すべきではありません)。代わりに、関数はそのデータ構造の更新されたバージョンを返す必要があります。最も一般的な方法は、必要な値のタプルを返すことです。おそらく探しているものは次のとおりです。

check:: [String] -> Char -> (Char, [String])
check s c 
    | any (elem c) s = check s (next c)
    | otherwise = (c, s ++ [[c]])

このようにして、「この」文字と Strings の最初のリストの更新版を取得します。

于 2016-04-11T06:58:21.220 に答える