<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">Hi.</div>
<div class="moz-cite-prefix"><br>
</div>
<blockquote type="cite"
cite="mid:A2A20EC3B8560D408356CAC2FC148E53016CF57EB5@SUN-DAG3.synchrotron-soleil.fr">
<pre class="moz-quote-pre" wrap="">I end up with this type.
data Hdf5M a
= H5Root (Hdf5M a)
| H5Group ByteString [Hdf5M a] -- A group can contain other groups and/or datasets
| forall sh b. (NativeType b, Shape sh) => H5Dataset ByteString (Array F sh b)
[…]
And I would like to be able to describe a contain like this
hdf5 $ do
group "name" $ do
dataset "name1" array1
dataset "name2" array2
group "other-name" $ do
etc...
</pre>
</blockquote>
<p>You don't need a monad instance for this. First of all, you don't
even need do syntax to make something "pretty" similar to this.</p>
<pre class="moz-quote-pre" wrap=""> hdf5 $
group "name" $
[ dataset "name1" array1
, dataset "name2" array2
, group "other-name" $ [
…</pre>
<p>But if you insist, you can just use an existing monad like
WriterT. For example (simplified):</p>
<pre> data Composite a = Base a | Composite [Composite a]
type CompositeWriter a = Writer [Composite a] ()
base = tell . pure . Base
composite = censor (pure . Composite)
asComposite = Composite . snd . runWriter
test = asComposite $ do
base 'a'
base 'b'
composite $ do
base 'c'
base 'd'
</pre>
<p>Hope that helps.<br>
</p>
</body>
</html>