ここで使ったコードの全体はGitHubに格納していますので、必要に応じて参照してください。GitHubC++でC++でのコードはいたって簡単です。forループで検索をかけて、見つかったら途中で関数を脱出、見つからなかったら、条件を替えて最初からforループで検索をやりなおす。この最初からループをやりなおす、がバックトラッキングになっています。-1;}Prologで「マッチングに失敗したらやりなおし」という部分に気がついたとき、最初に頭に浮かんだのが「だったらPrologで書けそうだな」ということでした。Prolog力が充分に鍛えられていないのでコードがスパッと浮かんでくるところまでいたっていないのですが、試行錯誤しつつ目的のコードにたどり着きました。エントリはsearchです。バックトラッキングはProlog自身が持っているのでコードとしては明記してません。逆になにも指定しないと可能なかぎりバックトラッキングが発生するので、3つ連続があったばあい、3つ連続を検出すると同時に2つ連続も検出してしまいます。そのためそれぞれにカット(!)を指定してバックトラッキングを止める必要があります。!.HaskellでPrologでできるならHaskellでもできるだろう...と何の根拠もなく着手したまではよかったのですが、末尾まで検索して見つからなかったときに検索結果をチャラにして最初から検索する、という部分が当初思いつかず。最初のデータを持ち回って、失敗したらその持ち回ったデータを突っ込んで続きを検索させるとかやってみたんですが、ものすごい不格好。いうか、それ絶対どっか間違ってる。nだったらその値を採用し、Nothingだったら次の関数を評価する、というしくみが思いつかず。思いつかないものの、Haskellはそのようなしくみを持っているはず、と検索をした結果みつけました。答えは手元にありました。「すごいHaskellたのしく学ぼう!」の第13章「モナドがいっぱい」で解説されているmplusがまさに探している関数でした。21つめの値がNothingでなければ、2つめの値が何であっても、式全体の値は1つめの値になります。1つめの値がNothingであれば、2つめの値が式全体の値になります。