2

これは私がデバッグするように割り当てられたHaskellプログラムの一部です:

process :: Sentence -> IO ()
process this@(Sentence string _) = do
  render string
  render "==>"
  render $ translate this

render = putStrLn

data Sentence = Sentence String Task

translate :: Sentence -> String     ; Incomplete Definition
translate (Sentence string task)
  | ...

  | ...

  | ...

  | ...

私が理解または認識していないこのプログラムの唯一の部分は、process this@(Sentence string _) = do 私が今まで見たことがない行でthis@あり、アンダースコアが何を(Sentence string _)意味するのかもよくわかりません。

4

3 に答える 3

7

this@「as-pattern」_の例ですが、はワイルドカードパターンの例です。ワイルドカードパターンは、パターン内のその時点での値を気にしない場合に使用されるため_、パターン内は何とでも一致し、ローカル名/変数をバインドしません。

一方、余分なローカル名/変数をバインドし、それと照合する場合は、asパターンを使用します。あなたはそれを考えることができます

process this@(Sentence string _) = ...

ほぼ同等です

process this = let (Sentence string _) = this
               in ...

記号の左側にある追加の名前を、@一致するものの値にバインドします。atパターン自体はすべてに一致しますが、記号の右側の内側のパターン@も一致するものと一致します。そのパターンはすべてに一致するわけではなく、この場合はSentenceコンストラクターのみに一致します。

このため、letバインディングのパターン一致が失敗する可能性がある場合、atパターンバージョンとletバインディングのあるバージョンの動作は異なります。したがって、関数に複数のケースを定義する場合は、atパターンが好まれます。関数のどのケースが呼び出されるかに影響を与える内部パターン。例えば

safeHead xs = let (x:_) = xs in Just x
safeHead [] = Nothing

[]最初の引数のパターンマッチングがxs成功するため、。で呼び出されると失敗します。そのため、関数の最初のケースが呼び出され、。xsと照合できません(x:_)。ただし、これをasパターンで記述した場合:

safeHead xs@(x:_) = Just x
safeHead [] = Nothing

[]関数の最初のケースを使用する前に内部パターンもチェックされるため、withの呼び出しは正常に機能します。したがって、とは一致しxsますが、は失敗し、2番目のケースが呼び出されます。特に2回目はxsを使用しないため、これは非常にばかげた例だと思いますが、違いがわかることを願っています。[](x:_)[]

于 2013-03-07T18:48:32.743 に答える
4

は、一致するものに名前を付けることができるasパターン@を定義します。この場合、一致する値に付けられた名前です。thisSentence

于 2013-03-07T18:34:03.203 に答える
4

Sentenceパターン内でaStringとaをとるコンストラクターであるということは、文全体に名前を付け、文に名前を付けるasパターンであり、アンダースコアは、他の方法で名前が付けられる場所に移動し、基本的には無視する必要があることを示します。Taskthis@(Sentence string _)thisstringStringTaskTask

于 2013-03-07T18:42:30.233 に答える