私は、パターンマッチングに関して、Haskellのリストの理解がどのように「フードの下で」機能しているかを理解しようとしています。次GHCiの出力は私のポイントを示していますパターンマッチが失敗した場合、Haskellのリスト内包表記でエラーが発生するのはなぜですか?
Prelude> let myList = [Just 1, Just 2, Nothing, Just 3]
Prelude> let xs = [x | Just x <- myList]
Prelude> xs
[1,2,3]
Prelude>
あなたが見ることができるように、「何を」スキップないとだけ「ジャスト」の値を選択することができます。私はそのリストのように定義されたモナド、であることを理解(実世界Haskellの、CHからソース14。):
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
xs >> f = concat (map (\_ -> f) xs)
fail _ = []
そのため、リスト内包表記は、基本的にはリスト内包で選択したすべての要素のシングルトンリストを構築し、それらを連結します。あるステップでパターンマッチが失敗した場合は、代わりに「失敗」関数の結果が使用されます。言い換えると、 "Just x"パターンが一致しないので、[concat]が呼び出されるまで[]がプレースホルダとして使用されます。これは、「何もない」がスキップされたように見える理由を説明します。
私が理解できないことは、ハスケルが「失敗」機能を呼び出すことをどのように知っているかということです。それは "コンパイラの魔法"ですか、それともHaskellで自分自身で書くことができる機能ですか?リストの理解と同じように機能するために、次の「選択」機能を書くことは可能ですか?
select :: (a -> b) -> [a] -> [b]
select (Just x -> x) myList -- how to prevent the lambda from raising an error?
[1,2,3]
ありがとうございます!このレスポンスは、私が読んできたものと一致し、list以外のタイプのパターンマッチの動作を説明します。コンパイラがこのようなcase文を使って、いつ呼び出すべきかを判断するのは私には起こりませんでした。これは完全に理にかなっています。 – Cybis