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
Dictdatatype. For exampleEach element in this record will have form
Dict (Identity _).Dictis defined asNow you simply need a traversal function which can handle a
(Dict Show :. Identity) aas an input.Note that you don't need a
Showconstraint ona- theShowclass dictionary is stored in theDictdatatype. You can rtraverse with this function.