我正在努力开发一个文本编辑器Rasa。
目前,我正在构建跟踪视口/分割区域的系统(类似于vim分割区域)。对我来说,将这个结构表示为树形结构是很自然的:
data Dir = Hor
| Vert
deriving (Show)
data Window a =
Split Dir SplitInfo (Window a) (Window a)
| Single ViewInfo a
deriving (Show, Functor, Traversable, Foldable)
这很好用,我将我的
View
存储在树中,然后可以遍历/映射它们以改变它们,它也很好地与lens包结合使用!最近我一直在学习递归方案,似乎这是一个适合使用它们的场景,因为该树是一个递归数据结构。
我设法弄清楚了如何构建出Fixpoint版本:
data WindowF a r =
Split Dir SplitInfo r r
| Single ViewInfo a
deriving (Show, Functor)
type Window a = Fix (WindowF a)
然而,现在Functor实例已被
r
使用;我尝试了几种变化:
deriving instance Functor Window
但它卡住了,因为window是一个类型同义词。
以及:
newtype Window a = Window (Fix (WindowF a)) deriving Functor
那也失败了;
• Couldn't match kind ‘* -> *’ with ‘*’
arising from the first field of ‘Window’ (type ‘Fix (WindowF a)’)
• When deriving the instance for (Functor Window)
- 是否仍然可以在
a
上定义 fmap/traverse?还是我需要使用 recursion-schemes 原语执行这些操作?我应该实现 Bifunctor 吗?实例实现会是什么样子?
其余类型在 这里,项目无法编译,因为我没有 Window 的适当 Functor 实例...
谢谢!