1. ホーム
  2. haskell

Haskellの<|>演算子は何をするのですか?

2023-10-21 01:37:38

質問

Haskellのドキュメントを見るのは、私にとっていつもちょっとした苦痛です。なぜなら、関数について得られるすべての情報は、しばしばただそれだけのものだからです。 f a -> f [a] としか書かれていないことが多いからです。

の場合と同様に <|> という関数があります。

与えられたのはこれだけです。 (<|>) :: f a -> f a -> f a であり、それは 連想二項演算です。 ...

を調べると Control.Applicative を調べてみると、実装によっては一見関係なさそうなことをやっていることがわかります。

instance Alternative Maybe where
    empty = Nothing
    Nothing <|> r = r
    l       <|> _ = l

OK、つまり左がなければ右を返し、そうでなければ左を返すのですね。このことから、quot;left or right"演算子であると思われます。 || の歴史的な用途は "OR" です。

instance Alternative [] where
    empty = []
    (<|>) = (++)

ただし、ここでは単にリストの連結演算子を呼び出しているだけですが...。私のアイデアを分解してみると...

では、この関数はいったい何なのでしょうか?その用途は何なのか?物事の全体像の中でどこに位置するのでしょうか?

どのように解決するのか?

一般的には、以下のような意味です。 a <|> b のどちらかである。 a または b または a そして b を並行して行う。しかし、バックアップしてみましょう。

のような型クラスでの操作には、本当に、実用的な意味はないのです。 (<*>) あるいは (<|>) . これらの操作は、(1)法則によって、(2)インスタンス化によって、2つの方法で意味を与えられている。もし私たちが 特定の のインスタンス Alternative のインスタンスである場合、意味を直感するために利用できるのは(1)だけです。

つまり、"associative" とは、次のような意味です。 a <|> (b <|> c) と同じである。 (a <|> b) <|> c . これは便利なことで、私たちが気にするのは シーケンス で連結されたものを (<|>) で連結されたものであり、そのツリー構造ではありません。

その他の法則としては empty . 特に a <|> empty = empty <|> a = a . これらの法則は、"choice" や "parallel" による直感では、 "a or (something impossible) must be a" または "a alongside (empty process) is just a" と読めます。ということを表しています。 empty がある種の失敗モードであることを示しています。 Alternative .

他にも、どのように (<|>) / empty との対話 fmap から Functor ) または pure / (<*>) から Applicative の意味を理解するために前進する最良の方法かもしれません。 (<|>) をインスタンス化する型の非常に一般的な例を検討することです。 Alternative : a Parser .

もし x :: Parser Ay :: Parser B では (,) <$> x <*> y :: Parser (A, B) を解析します。 x で、次に y を順番に並べる。これに対して (fmap Left x) <|> (fmap Right y) のどちらかを x または y で始まる x というように、両方の解析の可能性を試すことができる。言い換えれば、これは ブランチ の分岐、選択、または並列パース宇宙を示します。