0

Haskell の初心者として、私は StackOverflow の評価の高い質問、新しい質問などを読んでいますが、今日は次の質問がありました。

Haskell:リスト上の隣接番号間の最小距離

「まあ、答えを見ずにやってみよう」と思いました。手始めに、私は次のように書きました。

neighborsDistance [] = []
neighborsDistance [a] = []
neighborsDistance (x:y:xs) = abs (x - y) : neighborsDistance (y:xs)

それから私はすることができminimum neighborsDistance [2,3,6,2,0,1,9,8] => 1ました。

しかし、私はエッジケースがどのように機能するかについてはあまり気にしていなかったので、おそらくMaybeを使用してみようと思いました. 「たぶん」値を許容するように再帰ルールを適応させる方法が必要だったので、Hoogle でData.Maybeを調べたところ、fromMaybe...これは私が望んでいたことのように見えました。

neighborsDistance [] = Nothing
neighborsDistance [a] = Just []
neighborsDistance (x:y:xs) = Just (abs (x - y) : fromMaybe [] neighborsDistance (y:xs))

しかし、それは私にnot in scope: fromMaybeエラーを与えました。主な質問は、「なぜそれがうまくいかなかったのか」です。

もう1つの質問は、このようなものを見るときの一般的なHaskellの考え方についてです。これはMaybeの悪い使い方ですか?head空のリストで呼び出されたときに例外がスローされるのに対して、Maybe 型が返されるのはなぜですか?

私が問題を得た質問は、距離計算を最小限の操作で統一しようとすることでした。大幅な効率を失うことなく、このように分割できると思います(最小、最大などで構成するなど)?

4

2 に答える 2

2

しかし、それは範囲内ではありませんでした: fromMaybe エラー。主な質問は、「なぜそれがうまくいかなかったのか」です。

import Data.Maybe (fromMaybe)ファイルの先頭にある必要があります。

Prelude 自体は、 、、およびimport Data.Maybeの定義を取得するために実行します。ただし、モジュールの 'where' 句内でインポートを実行し、これら 3 つの定義のみをエクスポートします。そのため、あまり一般的でない関数は手動でインポートする必要があります。MaybeJustNothing

これはMaybeの悪い使い方ですか?空のリストで呼び出されたときに head が例外をスローするのに対して、Maybe 型を返すのはなぜですか?

の使用headは、一般的に非理想的と見なされます。Safeパッケージは を提供しますが、headMayこれは を返しますMaybe

一方、Maybe [Int]ここでは a を返す必要はないと思います。空のリストは、有効な結果がないという考えをすでにエンコードしています。実際、これは と の として十分に一般的に使用されていMaybeます。それをラップすると、値を「ラップ解除」するためにより多くの労力を費やす必要があります。maybeToListlistToMaybeMaybe

大幅な効率を失うことなく、このように分割できると思います(最小、最大などで構成するなど)?

ほとんどの場合、はい。Haskell には近道の fusionがあります。

于 2014-07-27T08:25:15.690 に答える
0

あなたの主な質問は1行で答えることができます.あなたはおそらく欠けています:

import Data.Maybe

しかし、Maybe 値を使用することに全体的なストレスがかかるのはなぜでしょうか? この問題は長さ >= 2 の任意のリストに対して明確な答えがあるため、maybe 型を使用する必要はありません。Maybe 型は通常、この場合のように、関数が結果を返すかどうかわからない場合にのみ使用されます。

もう1つの質問は、このようなものを見るときの一般的なHaskellの考え方についてです。これはMaybeの悪い使い方ですか?空のリストで呼び出されたときに head が例外をスローするのに対して、Maybe 型を返すのはなぜですか?

考えてみてください:パッケージlistToMaybe内の関数として実装されているセーフ ヘッドがあるData.Maybe場合、空のケースも処理する必要がありますが、これは head が意図したものではありません (リストの最初の要素を抽出します)。

headおよび空リストの詳細については、すでに説明されているので、こちらを参照してください。

大幅な効率を失うことなく、このように分割できると思います(最小、最大などで構成するなど)?

はい、Haskellでそれを行うことができます。かなりきれいです。ヒントとして: ($)and(.)演算子は、これに関する親友です。

于 2014-07-27T08:25:48.507 に答える