Still working on my text editor Rasa.
At the moment I'm building out the system for tracking viewports/splits (similar to vim splits). It seemed natural to me to represent this structure as a tree:
data Dir = Hor
| Vert
deriving (Show)
data Window a =
Split Dir SplitInfo (Window a) (Window a)
| Single ViewInfo a
deriving (Show, Functor, Traversable, Foldable)
This works great, I store my View
s in the tree, and then I can traverse/fmap over them to alter them, it also dovetails with the lens package pretty well!
I've been learning about Recursion Schemes lately and it seems like this is a suitable use-case for them since the tree is a recursive data-structure.
I managed to figure it out well enough to build out the Fixpoint version:
data WindowF a r =
Split Dir SplitInfo r r
| Single ViewInfo a
deriving (Show, Functor)
type Window a = Fix (WindowF a)
However, now the Functor instance is used up by the r
;
I've tried a few variations of
deriving instance Functor Window
But it chokes because window is a type synonym.
And:
newtype Window a = Window (Fix (WindowF a)) deriving Functor
And that fails too;
• Couldn't match kind ‘* -> *’ with ‘*’
arising from the first field of ‘Window’ (type ‘Fix (WindowF a)’)
• When deriving the instance for (Functor Window)
- Is it still possible to define fmap/traverse over
a
? Or do I need to do these operations using recursion-schemes primitives? Do I implement Bifunctor? What would the instance implementation look like?
Rest of the types are here, the project doesn't compile because I don't have the proper Functor instance for Window...
Thanks!!