web-dev-qa-db-ja.com

ジッパーがコモナドである理由の理解

これは、前の質問の answer のフォローアップです。

_a:A_の各項目_List[A]_を関数def f(a:A, leftNeighbors:List[A]): Bで_b:B_にマップし、_List[B]_を生成する必要があるとします。

当然、リストでmapを呼び出すだけではなく、リストzipperを使用できます。ジッパーは、リスト内を移動するためのカーソルです。現在の要素(focus)とその隣接要素へのアクセスを提供します。

これで、fdef f'(z:Zipper[A]):B = f(z.focus, z.left)に置き換えて、この新しい関数_f'_を_Zipper[A]_のcobindメソッドに渡すことができます。

cobindは次のように機能します。ジッパーを使用して_f'_を呼び出し、次にジッパーを移動し、newを使用してcalls _f'_を移動します移動された」ジッパー、ジッパーを再度移動する、などのように...ジッパーがリストの最後に到達するまで続けます。

最後に、cobindは、タイプ_Zipper[B]_の新しいジッパーを返します。これはリストに変換できるため、問題は解決されます。

cobind[A](f:Zipper[A] => B):Zipper[B]bind[A](f:A => List[B]):List[B]の対称性に注意してください。そのため、ListMonadであり、ZipperComonadです。

理にかなっていますか?

112
Michael

この質問は「未回答」リストの上部に定期的に表示されるため、ここに回答として私のコメントをコピーさせてください-とにかく1年前からそれほど建設的なことは何もありません。

Listも同様に(複数の方法で)コマンドとして表示でき、Zipperはモナドとしてキャストできます(さまざまな方法で)。違いは、状態マシンにデータを建設的に「追加」することに焦点を当てているのか(それがMonadインターフェースの概要である)か、それから「破壊的に」状態を「抽出する」のか(Comonadはします)。

「この理解は理にかなっている」と述べられている質問に答えることは容易ではありません。ある意味ではそうしますが、別の意味ではしません。

1
KT.