You can use DataKinds extension and define a singleton type for ReadOnly/WriteOnly. The code roughly looks like:<div><br></div><div>data ReadWrite = ReadOnly | WriteOnly</div><div><br></div><div>newtype Conn (a :: ReadWrite) = ...</div><div><br></div><div>openConn :: MonadIO m => Sing a -> m (Conn a)</div><div><br></div><div>In the implementation of openConn you can pattern match on Sing a and recover ReadOnly/WriteOnly both on term/type level. The singletons package provide utilities to ease writing this style of code.<br><br><div class="gmail_quote"><div dir="ltr">On Tue, Feb 27, 2018, 10:56 PM Brian Hurt <<a href="mailto:bhurt@spnz.org">bhurt@spnz.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I'm looking for pointers on how to do something.  What I'm trying to do: I want to define a newtype wrapper for database connections with a phantom type to control whether the connection is read-only or read-write.  So I have:<div><br></div><div>    newtype Conn a = Conn { unConn :: Connection }</div><div><br></div><div>    data ReadOnly = ReadOnly</div><div><br></div><div>    data ReadWrite = ReadWrite</div><div><br></div><div>    -- Simplifying here</div><div>    openConn :: MonadIO m => a -> Conn a</div><div><br></div><div>    query :: (MonadIO m, ToRow r, FromRow s) => Conn a -> Query -> r -> m [s]</div><div><br></div><div>    execute :: (MonadIO m, ToRow r) => Conn a -> Query -> r -> m Int64</div><div><br></div><div>But I want to be able to restrict the type a to be either ReadOnly or ReadWrite.  Solutions I've come up with so far are:</div><div><br></div><div>- Don't bother.  Later function calls put enough of constraint on the types that it isn't really necessary.  Or rather, ReadWrite is necessary, but ReadOnly isn't.</div><div><br></div><div>- Define some type class that ReadWrite and ReadOnly implement, but don't export the body of the typeclass from the module, preventing other people from implementing it for other types.</div><div><br></div><div>- Some sort of trickiness with closed type families that I haven't worked out yet.</div><div><br></div><div>Are their alternatives I haven't considered yet?</div><div><br></div><div>Thanks.</div><div><br></div><div>Brian</div><div><br></div></div>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div></div>