3
Prelude> let filter' p (x:xs) | p x = x : filter' p xs | otherwise = filter' p xs
Prelude> let filter' _ [] = []
Prelude> filter' odd [1..10]
*** Exception: <interactive>:1:5-21: Non-exhaustive patterns in function filter'

どのパターンが欠けていますか?

Prelude> :{
Prelude| let filter' p (x:xs)
Prelude|     | p x              = x : filter' p xs
Prelude|     | otherwise        = filter' p xs
Prelude| let filter' _ []       = []
Prelude| :}

<interactive>:2:5: parse error (possibly incorrect indentation)

ghciでこれを(構文的に)定義する慣用的な方法は何ですか? =以下の句を定義する前に、これらの句のためにいくつのスペースを空ける必要があるかわかりません。:{}: とは何ですか、もっと良い方法はありますか?

4

5 に答える 5

10

ここには2つの問題があります。まず、複数のletステートメントを使用すると、2つの別個の定義が作成され、後者は前者をシャドウイングします。次に、構文エラーの理由は、ガードを十分にインデントしなかったためです(| px ...行はさらにインデントする必要がありますfilter' p (x:xs))。

定義をファイルに保存する方が簡単ですが、GHCiに正しく入力する方法は次のとおりです。

Prelude> :{
Prelude| let filter' p (x:xs)
Prelude|      | p x       = x : filter' p xs
Prelude|      | otherwise = filter' p xs
Prelude|     filter' _ [] = []
Prelude| :}

:{andコマンドは、:}複数行にまたがる定義を入力するために使用されます。の位置合わせ=はオプションであり、重要なのは行のインデントです。

于 2012-09-18T21:02:32.633 に答える
4

ghciプロンプトで関数を記述しないでください-関数をMyFunctions.hs何かに保存して実行してください

:l MyFunctions

ghciで。

letghciのコマンドは以前の定義を消去するので、

let filter' p (x:xs) | p x = x : filter' p xs | otherwise = filter' p xs
let filter' _ [] = []

実際に行っているlet filter' p (x:xs) | p x = x : filter' p xs | otherwise = filter' p xsのは、その定義を完全に削除して、に置き換えることlet filter' _ [] = []です。

これNon-exhaustive patternsは、[1..10]でフィルターの2番目の定義を使用したことを意味します。これは空ではなく、フィルターの2番目のバージョンは空のリストのみをカバーします。

filter'' p (x:xs) | p x = x : filter' p xs | otherwise = filter' p xs醜いですが、あなたの定義はうまく機能し、インデントエラーはありません。ghciでワンライナーを書き込もうとしていたと思いますが、テキストエディター+ ghci + http://www.haskell.org/hoogle/は強力な組み合わせです!

于 2012-09-18T20:45:57.557 に答える
1

他の回答が指摘しているように、GHCiに新しいステートメントがあるたびにlet、以前の定義が上書きされます。letただし、定義を1つのステートメントに入れることで、パターンマッチングを使用できます。これを行うには、基本的に2つの方法があります。

まず、セミコロンを使用します。

let filter' p [] = []; filter' p (x:xs) | p x = x : filter' p xs | otherwise = filter' p xs

次に、使用:{ ... :}とインデント。

:{
let filter' _ [] = []
    filter' p (x:xs)
      | p x = x : filter' p xs
      | otherwise = filter' p xs
:}

(コピー貼り付けを簡単にするために、プロンプトを省略しました。)

于 2012-09-18T21:02:33.847 に答える
1

Andrewの答えを詳しく説明するために、次のghciセッションを検討してください。

Prelude> let x = 1
Prelude> let x = 2
Prelude> x
2

つまりlet、ghciの式は新しい変数を導入し、古い定義をシャドウイングします。Andrewが提案したように、定義をファイルに保存するだけです。

于 2012-09-18T20:49:52.213 に答える