给定任何容器类型,我们可以形成(以元素为中心的)Zipper并且知道这个结构是Comonad.最近在针对以下类型的另一个Stack Overflow问题中详细探讨了这个问题:
data Bin a = Branch (Bin a) a (Bin a) | Leaf a deriving Functor
Run Code Online (Sandbox Code Playgroud)
使用以下拉链
data Dir = L | R
data Step a = Step a Dir (Bin a) deriving Functor
data Zip a = Zip [Step a] (Bin a) deriving Functor
instance Comonad Zip where ...
Run Code Online (Sandbox Code Playgroud)
这是一个情况Zip是Comonad,虽然它的实例的建设是一个有点毛.也就是说,Zip可以完全机械地衍生出来Tree并且(我相信)任何以这种方式衍生的类型都是自动的Comonad,所以我觉得应该是这样我们可以通用和自动地构造这些类型及其组合.
实现拉链构造的一般性的一种方法是使用以下类和类型族
data Zipper t a = Zipper { diff :: D t a, here …Run Code Online (Sandbox Code Playgroud) 我需要将列表拆分为所有可能元组的列表,但我不确定如何这样做.
例如:
pairs ["cat","dog","mouse"]
Run Code Online (Sandbox Code Playgroud)
应该导致:
[("cat","dog"), ("cat","mouse"), ("dog","cat"), ("dog","mouse"), ("mouse","cat"), ("mouse","dog")]
我能够形成前两个,但我不确定如何得到其余的.
这是我到目前为止所拥有的:
pairs :: [a] -> [(a,a)]
pairs (x:xs) = [(m,n) | m <- [x], n <- xs]
Run Code Online (Sandbox Code Playgroud)