I'm implementing some functionality on top of a zipper where the hole type is existentially quantified, i.e. I have something like this:
data Zipper (c :: Type -> Constraint) ... =
forall hole. (c hole, ...) =>
Zipper hole ...
where dots denote implementation details which I think are unrelated to my question. Consider now some data type:
data Tree = Fork Tree Tree | Leaf Int
What I would like to have is an ability to inspect my position in the tree. In case of simple recursion the standard way to achieve this is pattern matching:
case hole of
Fork _ _ -> doSomething
Leaf _ -> doSomethingElse
However, the type of hole is existentially quantified, so simple pattern matching won't do. The idea I had is to use a type class
class WhereAmI p a where
position :: a -> p a
data Position :: Type -> Type where
C_Leaf :: Position Tree
C_Fork :: Position Tree
-- possibly more constructors if we're traversing
-- multiple data structures
Then I can do stuff like
f :: Zipper (WhereAmI Position) Tree -> Int
f (Zipper hole _) = case position hole of
C_Leaf -> let (Leaf x) = hole in x
otherwise -> ...
What I would like, however, is to replace C_Leaf with something like at @"Leaf" (i.e. use the original constructor names) using some magic like this
class WhereAmI' p (a :: Symbol) where
position' :: Proxy a -> p
instance WhereAmI' (Position Tree) "Leaf" where
position' _ = C_Leaf
instance WhereAmI' (Position Tree) "Fork" where
position' _ = C_Fork
at :: forall a p. WhereAmI' p a => p
at = position (Proxy :: Proxy a)
This even works except that I can't use at as a pattern and I if I try to make it a pattern, GHC complains about a parse error in pattern...
Is there some clever way to achieve what I'm trying to describe here?
Zipperis really supposed to mean. - dfeueratas a pattern and if I try to make it a pattern, GHC complains about a parse error in pattern..." Did you know that pattern synonyms are supposed to be Capitalized? - luquifirst-class-patternswhich allows to treat patterns as values: hackage.haskell.org/package/first-class-patterns You could try to explore, whether it's possible to achieve your goal with this library. - Shersh