I have constructed a simple example of a Vinyl record. First, some language pragmas and imports:
{-# LANGUAGE DataKinds, TypeOperators #-}
import Data.Vinyl
import Data.Vinyl.Functor
import Control.Applicative
the actual example (it employs the HList type synonym for simplicity):
mytuple :: HList [Integer,Bool]
mytuple = Identity 4 :& Identity True :& RNil
This compiles ok. But now I want to print the Vinyl record using rtraverse:
printi :: Show a => Identity a -> IO (Identity a)
printi (Identity x) = print x *> pure (Identity x)
main :: IO ()
main = rtraverse printi mytuple *> pure ()
This gives the following error: No instance for (Show x) arising from a use of ‘printi’
. Which is expected I guess, because rtraverse
expects a function with no constraints.
How to solve this? It seems like reifyConstraint
will be a part of the solution, but I don't know how to use it.
You are correct that reifyConstraint will solve this problem. What this function does is convert (or "reify") constraints into datatypes, namely the
Dict
datatype. For exampleEach element in this record will have form
Dict (Identity _)
.Dict
is defined asNow you simply need a traversal function which can handle a
(Dict Show :. Identity) a
as an input.Note that you don't need a
Show
constraint ona
- theShow
class dictionary is stored in theDict
datatype. You can rtraverse with this function.