web-dev-qa-db-ja.com

Haskellレコードパターンマッチング

実際のデータが不要な場合に関数パターンを簡素化する方法を探しています。

data X = A | B String | C Int Int String
myfn :: X -> Int
myfn A = 50
myfn (B _) = 200
myfn (C _ _ _) = 500

値を破棄するだけで、Cを照合するためのより単純なパターンを作成する方法はありますか?

hsdevは「ヒント:レコードパターンを使用する」というヒントを追加しましたが、Googleは私を助けませんでした。

29
theduke

次のようなレコードパターンを使用できます。

data X = A | B {name :: String} | C {x::Int, y::Int, name::String}

myfn :: X -> Int
myfn A = 50
myfn B{} = 200
myfn C{} = 500

レコードパターンを使用すると、コンストラクタのフィールドに名前を付けることができます。次のようなこともできます:

myfn C{name=n} = length n

必要な特定のフィールドでのみパターンマッチできることがわかります。

注:レコード構文を使用しないデータ型でも、emptyレコードパターンを使用できます。

data A = A Int | B Int Int

myfn A{} = 1
myfn B{} = 2

これは大丈夫です。レコードパターンに関連する他の多くの拡張機能があります。

  • RecordWildCardsは、パターンC{..}と同等のC{x=x, y=y, name=name}のようなものを書くことができます。つまり、すべてのフィールドに一致し、スコープにxの値を持ちます。 xフィールドなどに一致.

  • NamedFieldPunsを使用すると、C{name}と同等のC{name=name}を記述できるため、nameがスコープ内にあり、nameに一致する値を含むようになります。フィールド。

レコードパターンを使用しても、コンストラクタを定位置で使用することを妨げないので、次のように記述できることに注意してください。

myfn (B _) = 200

adds機能のみです。

62
Bakuriu