4

パラメータのデータ型に関して、Haskell の関数定義の括弧の意味は何ですか。

例えば:

doStuff Name -> Age -> String
doStuff (NameConstr a) (AgeConstr b) = "Nom: " ++ a ++ ", age: " ++ b

以下は、事前にどこかで定義されています。

data Name = NameConstr String
data Age = AgeConstr Integer

ここで括弧の必要性を否定する方法で、関数パラメーター a と b をキャプチャできますか?

参考までに、私は取り組んでいます:

そして、私はまだこの詳細を把握することができないようです.

4

3 に答える 3

7

括弧がない場合、関数は 4 つのパラメーターを持つと見なされます。ただし、括弧を省略するとあいまいになる反例は考えられません。

必要に応じて、次のように型を再定義できます。

data Name = NameConstr { getName :: String  }
data Age  = AgeConstr  { getAge  :: Integer }

関数が次のようになるようにします。

doStuff n a = "Nom: " ++ getName n ++ ", age: " ++ show (getAge a)

(最後の部分を修正;aInteger文字列に連結できません)

于 2013-04-14T08:33:12.997 に答える
4

実際、括弧がまったくない (ネストされた) パターンの単純な文法を解析することは可能です。そのようなものを仮定します:

<PAT>  ::= <WILDCARD> | <VAR> | <CON0> | <CON1> <PAT> | <CON2> <PAT> <PAT> ...
<VAR>  ::= <LNAME>
<CON*> ::= <UNAME>
<WILD> ::= "_"

ここで、LNAME は小文字で始まる名前であり、UNAME は大文字で始まる名前です。解析中にコンストラクター名を検索して、そのアリティを確認する必要があります。次に、アリティ情報を使用してコンストラクタ フィールドを解析できます。しかし、この検索は非常に複雑になり、解析自体が遅くなる可能性があります。Haskell には、はるかに複雑なパターン (ビュー パターン、"as" パターン、レコード、任意の固定性を持つ中置コンストラクタなど) があり、括弧を省略するとあいまいさが生じる可能性があります。

それをしない別の理由がありますが。次のコードを検討してください。

data Bar = Bar Int
data Foo = Foo Int

libFunction Foo a Bar b = a + b
someUse bar foo = libFunction foo bar

次に、データ型を少し変更するとします。

data Bar = Bar
data Foo = Foo Int Bar Int

変更されたコードは型チェックを行う可能性がありますが、関数は期待どおりには機能しません。実際の例ではありませんが、それでも。また、Haskell には型クラスがあるため、どこに問題があるのか​​を見つけるのは非常に困難です。

言い換えれば、エラーメッセージの品質が低下する可能性があり、括弧は変更後の予期しない動作から私たちを守ります。

于 2013-04-14T10:41:28.813 に答える