이것은 이전 질문에 대한 답변 에 대한 후속 조치 입니다.
나는 각 항목을 매핑 할 필요가 가정 a:A
의 List[A]
에 대한 b:B
기능 def f(a:A, leftNeighbors:List[A]): B
및 생성 List[B]
.
당연히 map
목록에 전화 를 걸 수는 없지만 목록 지퍼를 사용할 수 있습니다 . 지퍼는 목록을 이동하는 커서입니다. 현재 요소 ( focus
) 및 인접 요소에 대한 액세스를 제공합니다 .
지금은 내를 대체 할 수 f
와 함께 def f'(z:Zipper[A]):B = f(z.focus, z.left)
이 새로운 기능을 전달할 f'
에 cobind
의 방법 Zipper[A]
.
cobind
다음과 같이 작동이 있음을 호출 f'
지퍼로, 다음 지퍼를 이동 전화 f'
와 새가 “이동”지퍼, 다시 등등, 그래서 지퍼를 이동 … 지퍼가 목록의 끝에 도달 할 때까지.
마지막으로 cobind
는 유형의 새 지퍼를 반환합니다.이 지퍼 Zipper[B]
는 목록으로 변환 될 수 있으므로 문제가 해결됩니다.
이제 사이의 대칭을주의 cobind[A](f:Zipper[A] => B):Zipper[B]
하고 bind[A](f:A => List[B]):List[B]
이유 있다고 List
입니다 Monad
및 Zipper
입니다 Comonad
.
말이 되나요?
답변
이 질문은 “답변이없는”목록의 맨 위에 정기적으로 나타나므로 여기에 내 의견을 답으로 복사 해 보겠습니다. 어쨌든 1 년 전 이후로 더 건설적인 것은 없었습니다.
ㅏ List
는 (여러 가지 방법으로) comonad로 볼 수있는 반면, a Zipper
는 (여러 가지 방법으로도) 모나드로 캐스팅 될 수 있습니다. 차이점은 개념적으로 데이터를 상태 머신에 건설적으로 “추가”하는 데 초점을 맞추는 지 ( Monad
인터페이스가 무엇인지 ) 아니면 “해체 적으로”상태를 “추출”하는지 (그것이하는 일입니다 Comonad
)입니다.
그러나 “이 이해가 타당합니까”라는 질문에 대답하는 것은 쉽지 않습니다. 어떤 의미에서는 그렇고, 다른 의미에서는 그렇지 않습니다.