So, I read a little about the Zipper template in Haskell (and other functional languages, I suppose) to navigate and change the data structure, and I thought it would be a good chance for me to hone my skills when creating type classes in Haskell, since the class can provide a general workaround interface for me to write code, regardless of the data structure passed.
I thought that I probably needed two classes: one for the root data structure and one for the special data structure created to go through the first:
module Zipper where class Zipper z where go'up :: z -> Maybe z go'down :: z -> Maybe z go'left :: z -> Maybe z go'right :: z -> Maybe z class Zippable t where zipper :: (Zipper z) => t -> z get :: (Zipper z) => z -> t put :: (Zipper z) => z -> t -> z
But when I tried them with some simple data structures like a list:
Or a binary tree:
I could not compile it, I would get as many errors as this for each of the Zippable instance Zippable :
Zipper.hs: 28: 14:
Couldn't match expected type `z '
against inferred type `ListZipper a '
`z 'is a rigid type variable bound by
the type signature for `zipper 'at Zipper.hs: 10: 20
In the expression: ListZipper {preceding = [], following = as}
In the definition of `zipper ':
zipper as = ListZipper {preceding = [], following = as}
In the definition for method `zipper '
So I'm not sure where to go from here. I suspect my problem is that I am trying to link the two instances together when the declaration (Zipper z) => just wants z be any Zipper .
source share