Re: Functional design question

"Albert Y. C. Lai" <[email protected]> Sun, 22 Mar 2026 20:09:37 -0400
Newsgroups gmane.comp.lang.haskell.cafe
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--===============4565469499305064897==
Content-Type: multipart/alternative;
 boundary="------------t1LL3Y0m2zEGpXho7ivhnMND"
Content-Language: en-US

This is a multi-part message in MIME format.
--------------t1LL3Y0m2zEGpXho7ivhnMND
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: base64

UGVyaGFwcw0KDQpEaXJlY3RvcnlDb25maWc8Qz4gew0KICAgUGFpcjxQYXRoLEM+IHBhdGgN
CiAgIFBhaXI8U3RyaW5nLEM+IGZpbGUNCn0NCg0KQ29udGV4dCB7DQogICBTdHJpbmcgZmls
ZW5hbWUNCiAgIGludCBsaW5lTnVtYmVyLCBjb2x1bW5OdW1iZXINCn0NCg0KUGFpciBpcyBh
IDItdHVwbGUgdHlwZS4NCg0KVW5pdCBpcyBhbiBpbmZvcm1hdGlvbmxlc3MgdHlwZS4NCg0K
VGhlbiB5b3UgY2FuIGhhdmUgRGlyZWN0b3J5Q29uZmlnPENvbnRleHQ+IGFuZCBEaXJlY3Rv
cnlDb25maWc8VW5pdD4uDQoNCk9uIDMvMjIvMjYgMTk6MTAsIEpvYWNoaW0gRHVyY2hob2x6
IHdyb3RlOg0KPiBIaSBhbGwsDQo+DQo+IEkgaGF2ZSBzb21lIGRlc2lnbiBxdWVzdGlvbnMg
LSBub3QgZm9yIEhhc2tlbGwgYnV0IGZvciB0aGUgSmF2YStWYXZyIA0KPiBjb21ibywgYnV0
IEkgYW0gYWJvdXQgdG8gZGlwIG15IHRvZXMgaW50byBhY3R1YWwgd29yayBpbiBhIGZ1bmN0
aW9uYWwgDQo+IG1hbm5lciwgYXMgZmFyIGFzIHRoYXQgaXMgcG9zc2libGUsIGFuZCBJIHRo
b3VnaHQgSSBtaWdodCBhcyB3ZWxsIGdvIA0KPiBmb3IgdGhlIGNvbW11bml0eSB0aGF0J3Mg
YmVzdCBzdWJzY3JpYmVkIHRvIGEgcHVyZWx5IGZ1bmN0aW9uYWwgc3R5bGUuDQo+DQo+IEJp
cmQncyBleWUgdmlldzoNCj4NCj4gSmF2YSBldmVyeWJvZHkga25vd3MgKEkgZG9uJ3QgbGlr
ZSBpdCBlaXRoZXIsIG5vIHdvcnJpZXMpLCBWYXZyIGlzIGEgLSANCj4gdG8gbXkgZXllcyAt
IHByZXR0eSBuaWNlIGZ1bmN0aW9uYWwgbGlicmFyeSwgaHR0cHM6Ly9kb2NzLnZhdnIuaW8v
IGZvciANCj4gZGV0YWlscyBpZiB5b3UncmUgYWN0dWFsbHkgaW50ZXJlc3RlZC4NCj4gSSB3
YW50IHRvIGxldmVyYWdlIFZhdnIgdG8gZ2V0IGEgSmF2YSBwcm9ncmFtIHRvIGJlIGFzIEhh
c2tlbGwtaXNoIGFzIA0KPiBpcyByZWFzb25hYmxlOyB0aGF0J3Mgbm90IGdvaW5nIHRvIGJl
IG11Y2ggYnkgYSBIYXNrZWxsZXIncyBzdGFuZGFyZHMsIA0KPiBidXQuLi4gYmFieSBzdGVw
cy4NCj4NCj4gQXBwbGljYXRpb24gaXMgYSBzaW1wbGUgY29tbWFuZC1saW5lIHRoaW5nOiBS
ZWFkIGNvbmZpZ3VyYXRpb24gZnJvbSANCj4gY29tbWFuZCBsaW5lIGFuZCBjb25maWd1cmF0
aW9uIGZpbGUsIGVtaXQgZGlhZ25vc3RpY3MgYWJvdXQgYW55IGVycm9ycyANCj4gaW4gdGhl
IGNvbmZpZywgdGhlbiBwcm9jZXNzLg0KPiBJIHdhbnQgdGhlIGNvbmZpZ3VyYXRpb24gcHJv
Y2Vzc2luZyB0byBiZSBhcyBmdW5jdGlvbmFsIGFzIHJlYXNvbmFibGUsIA0KPiBnaXZlbiB0
aGUgY29uc3RyYWludHMuIEhvd2V2ZXIsIEknbSB1bmRlY2lkZXMgYWJvdXQgbWFueSB0aGlu
Z3MsIG5vIA0KPiBkb3VidCBiZWNhdXNlIEkgc2ltcGx5IGRvbid0IGtub3cgdGhlIGJlc3Qg
ZGVzaWduIHBhdHRlcm5zLCBhbmQgaXQncyANCj4gZnJ1c3RyYXRpbmcgdG8gc2VlIG11bHRp
cGxlIG9wdGlvbnMgYW5kIG5vdCBrbm93aW5nIHdoaWNoIG9uZXMgd2lsbCANCj4gcGFpbnQg
bWUgaW50byBhIGNvcm5lciBhbmQgd2hpY2ggb25lcyB3aWxsIG5vdC4NCj4NCj4gVGhpbmdz
IEknbSB1bmRlY2lkZWQgYWJvdXQ6DQo+DQo+IGEpIERhdGEgdHlwZSB2YXJpYXRpb25zDQo+
IER1cmluZyB0aGUgY29uZmlndXJhdGlvbiBwaGFzZSwgSSBuZWVkIHRvIGNhcnJ5IGluZm9y
bWF0aW9uIGFib3V0IA0KPiB3aGVyZSBzb21lIGNvbmZpZ3VyYXRpb24gaXRlbSBjYW1lIGZy
b20gKGl0cyAoImNvbnRleHQiLCB1c3VhbGx5IGZpbGUsIA0KPiBsaW5lIG51bWJlciwgY29s
dW1uIG51bWJlcikuDQo+IEluIHRoZSBwcm9jZXNzaW5nIHBoYXNlLCBjb25maWd1cmF0aW9u
IGlzIGNvbnNpZGVyZWQgZmluYWwgYW5kIA0KPiBlcnJvci1mcmVlLCBzbyBjb250ZXh0IGlz
IG5vdCBuZWVkZWQgKHRoYXQncyBhIGRvbmUgZGVzaWduIGRlY2lzaW9uKS4NCj4gSSBjb3Vs
ZCBjYXJyeSBjb250ZXh0IGluZm9ybWF0aW9uIGludG8gdGhlIHByb2Nlc3NpbmcgcGhhc2Us
IGJ1dCBpdCdzIA0KPiBnb2luZyB0byBiZSBhd2t3YXJkOiBTYXksIHdlIGhhdmUgdGhlIGZv
bGxvd2luZyB0eXBlcyAoZm9yZ2l2ZSB0aGUgDQo+IG1vc3QgdW4tSGFza2VsbGlzaCBwc2V1
ZG8gc3ludGF4IGJ1dCBJIGRvbid0IGRhcmUgdG8gdXNlIEhhc2tlbGwgc3R5bGUgDQo+IGJl
Y2F1c2UgSSdkIGFsbW9zdCBjZXJ0YWlubHkgZ2V0IHRoYXQgd3JvbmcgYW5kIHByb3Zva2Ug
DQo+IG1pc3VuZGVyc3RhbmRpbmdzKQ0KPiDCoCBEaXJlY3RvcnlDb25maWcgew0KPiDCoMKg
wqAgQ29uZmlnRGF0YTxQYXRoPiBwYXRoDQo+IMKgwqDCoCBDb25maWdEYXRhPFN0cmluZz4g
dGl0bGUNCj4gwqDCoMKgIC4uLg0KPiDCoCB9DQo+IMKgIGRhdGEgQ29uZmlnRGF0YTxhPiB7
DQo+IMKgwqDCoCBTdHJpbmcgZmlsZU5hbWUNCj4gwqDCoMKgIGludCBsaW5lTnVtYmVyDQo+
IMKgwqDCoCBpbnQgY29sdW1uTnVtYmVyDQo+IMKgwqDCoCBhIHZhbHVlDQo+IMKgIH0NCj4g
YnV0IGluIHRoZSBwcm9jZXNzaW5nIHBoYXNlIEkgZG9uJ3Qgd2FudCBteSBjb25maWcgb2Jq
ZWN0cyBwb2xsdXRlZCANCj4gd2l0aCBjb250ZXh0LCBzbyBJIHdhbnQNCj4gwqAgRGlyZWN0
b3J5Q29uZmlnIHsNCj4gwqDCoMKgIFBhdGggcGF0aA0KPiDCoMKgwqAgU3RyaW5nIHRpdGxl
DQo+IMKgwqDCoCAuLi4NCj4gwqAgfQ0KPiBObyBpZGVhIGhvdyB0byBkZWFsIHdpdGggdGhh
dC4gSSdkIHVzZSBjb2RlIGdlbmVyYXRpb24gaW4gSmF2YSBJIA0KPiBndWVzcywgYnV0IHRo
YXQncyBob3JyaWJseSBpbmVsZWdhbnQgYW5kIGNvbXBsaWNhdGVkIHRvIHNldCB1cCAobm8s
IEkgDQo+IGRvbid0IHBhcnRpY3VsYXJseSBsaWtlIEphdmEsIGl0J3MganVzdCB3aGF0IEkn
bSBjdXJyZW50bHkgdXNpbmcpLg0KPiBTby4uLiBob3cgd291bGQgb25lIGRvIHN1Y2ggYSB0
aGluZyBpbiBhIGZ1bmN0aW9uYWwgbGFuZ3VhZ2U/DQo+IE5vdCBuZWNlc3NhcmlseSBIYXNr
ZWxsLCBJIGd1ZXNzIHNvbWUgbGFuZ3VhZ2UgZXh0ZW5zaW9ucyBleGlzdCBmb3IgDQo+IHRo
YXQga2luZCBvZiBzdHVmZiwgYnV0IEknbSBtb3JlLW9yLWxlc3MgdGllZCB0byBKYXZhICsg
ZnVuY3Rpb25hbCANCj4gbGlicmFyaWVzLCBzbyBJJ2xsIGhhdmUgdG8gc3RpY2sgd2l0aCB0
aGUgbW9yZSBiYXNpYyBhcHByb2FjaGVzIG1vc3QgDQo+IGxpa2VseS4gQmVzaWRlcywgZXZl
biBpZiBJIGRpZCBIYXNrZWxsLCBJJ2Qgd2FudCB0byBhdm9pZCB0aGUgYWR2YW5jZWQgDQo+
IHN0dWZmIHVudGlsIEkgZ2V0IGNvbmZpZGVudCBpbiB0aGUgYmFzaWNzLg0KPg0KPiBUTDtE
UjogSSBoYXZlIGEgZGVlcGx5IG5lc3RlZCBjb25maWd1cmF0aW9uIGRhdGEgc3RydWN0dXJl
IHdoZXJlIGVhY2ggDQo+IGZpZWxkIGhhcyBhICJjb250ZXh0IiwgaS5lLiB0aGUgcGxhY2Ug
aXQgY2FtZSBmcm9tOyBob3cgdG8gSSBtYWtlIGl0IA0KPiBzbyB0aGF0IHRoZSBjb250ZXh0
IGlzIGF2YWlsYWJsZSBkdXJpbmcgY29uZmlndXJhdGlvbiBldmFsdWF0aW9uIGJ1dCANCj4g
aXMgdW5hdmFpbGFibGUgaW4gdGhlIGxhdGVyIHByb2Nlc3NpbmcgcGhhc2U/DQo+DQo+IEkg
aG9wZSB0aGlzIGlzIHVuZGVyc3RhbmRhYmxlOyBpdCdzIHJlYWxseSBoYXJkIHRvIGRvIHRo
YXQgd2hlbiB5b3UgDQo+IGRvbid0IGV2ZW4ga25vdyBlbm91Z2ggdG8gYXNrIHRoZSBxdWVz
dGlvbnMgcHJlY2lzZWx5IGVub3VnaC4NCj4NCj4gUmVnYXJkcywNCj4gSm8NCj4gX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NCj4gSGFza2VsbC1D
YWZlIG1haWxpbmcgbGlzdCAtLSBoYXNrZWxsLWNhZmVAaGFza2VsbC5vcmcNCj4gVG8gKHVu
KXN1YnNjcmliZSwgbW9kaWZ5IG9wdGlvbnMgb3IgdmlldyBhcmNoaXZlcyBnbyB0bzoNCj4g
T25seSBtZW1iZXJzIHN1YnNjcmliZWQgdmlhIHRoZSBtYWlsbWFuIGxpc3QgYXJlIGFsbG93
ZWQgdG8gcG9zdC4NCg==
--------------t1LL3Y0m2zEGpXho7ivhnMND
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3DUTF=
-8">
  </head>
  <body>
    <p>Perhaps</p>
    <pre>DirectoryConfig&lt;C&gt; {
  Pair&lt;Path,C&gt; path
  Pair&lt;String,C&gt; file
}

Context {
  String filename
  int lineNumber, columnNumber
}</pre>
    <p><font face=3D"monospace">Pair</font> is a 2-tuple type.</p>
    <p><font face=3D"monospace">Unit</font> is an informationless type.</=
p>
    <p>Then you can have <font face=3D"monospace">DirectoryConfig&lt;Cont=
ext&gt;</font>
      and <font face=3D"monospace">DirectoryConfig&lt;Unit&gt;</font>.</p=
>
    <div class=3D"moz-cite-prefix">On 3/22/26 19:10, Joachim Durchholz
      wrote:<br>
    </div>
    <blockquote type=3D"cite"
      cite=3D"mid:[email protected]">Hi
      all,
      <br>
      <br>
      I have some design questions - not for Haskell but for the
      Java+Vavr combo, but I am about to dip my toes into actual work in
      a functional manner, as far as that is possible, and I thought I
      might as well go for the community that's best subscribed to a
      purely functional style.
      <br>
      <br>
      Bird's eye view:
      <br>
      <br>
      Java everybody knows (I don't like it either, no worries), Vavr is
      a - to my eyes - pretty nice functional library,
      <a class=3D"moz-txt-link-freetext" href=3D"https://docs.vavr.io/">h=
ttps://docs.vavr.io/</a> for details if you're actually interested.
      <br>
      I want to leverage Vavr to get a Java program to be as Haskell-ish
      as is reasonable; that's not going to be much by a Haskeller's
      standards, but... baby steps.
      <br>
      <br>
      Application is a simple command-line thing: Read configuration
      from command line and configuration file, emit diagnostics about
      any errors in the config, then process.
      <br>
      I want the configuration processing to be as functional as
      reasonable, given the constraints. However, I'm undecides about
      many things, no doubt because I simply don't know the best design
      patterns, and it's frustrating to see multiple options and not
      knowing which ones will paint me into a corner and which ones will
      not.
      <br>
      <br>
      Things I'm undecided about:
      <br>
      <br>
      a) Data type variations
      <br>
      During the configuration phase, I need to carry information about
      where some configuration item came from (its ("context", usually
      file, line number, column number).
      <br>
      In the processing phase, configuration is considered final and
      error-free, so context is not needed (that's a done design
      decision).
      <br>
      I could carry context information into the processing phase, but
      it's going to be awkward: Say, we have the following types
      (forgive the most un-Haskellish pseudo syntax but I don't dare to
      use Haskell style because I'd almost certainly get that wrong and
      provoke misunderstandings)
      <br>
      =C2=A0 DirectoryConfig {
      <br>
      =C2=A0=C2=A0=C2=A0 ConfigData&lt;Path&gt; path
      <br>
      =C2=A0=C2=A0=C2=A0 ConfigData&lt;String&gt; title
      <br>
      =C2=A0=C2=A0=C2=A0 ...
      <br>
      =C2=A0 }
      <br>
      =C2=A0 data ConfigData&lt;a&gt; {
      <br>
      =C2=A0=C2=A0=C2=A0 String fileName
      <br>
      =C2=A0=C2=A0=C2=A0 int lineNumber
      <br>
      =C2=A0=C2=A0=C2=A0 int columnNumber
      <br>
      =C2=A0=C2=A0=C2=A0 a value
      <br>
      =C2=A0 }
      <br>
      but in the processing phase I don't want my config objects
      polluted with context, so I want
      <br>
      =C2=A0 DirectoryConfig {
      <br>
      =C2=A0=C2=A0=C2=A0 Path path
      <br>
      =C2=A0=C2=A0=C2=A0 String title
      <br>
      =C2=A0=C2=A0=C2=A0 ...
      <br>
      =C2=A0 }
      <br>
      No idea how to deal with that. I'd use code generation in Java I
      guess, but that's horribly inelegant and complicated to set up
      (no, I don't particularly like Java, it's just what I'm currently
      using).
      <br>
      So... how would one do such a thing in a functional language?
      <br>
      Not necessarily Haskell, I guess some language extensions exist
      for that kind of stuff, but I'm more-or-less tied to Java +
      functional libraries, so I'll have to stick with the more basic
      approaches most likely. Besides, even if I did Haskell, I'd want
      to avoid the advanced stuff until I get confident in the basics.
      <br>
      <br>
      TL;DR: I have a deeply nested configuration data structure where
      each field has a "context", i.e. the place it came from; how to I
      make it so that the context is available during configuration
      evaluation but is unavailable in the later processing phase?
      <br>
      <br>
      I hope this is understandable; it's really hard to do that when
      you don't even know enough to ask the questions precisely enough.
      <br>
      <br>
      Regards,
      <br>
      Jo
      <br>
      _______________________________________________
      <br>
      Haskell-Cafe mailing list -- <a class=3D"moz-txt-link-abbreviated" =
href=3D"mailto:[email protected]">[email protected]</a>
      <br>
      To (un)subscribe, modify options or view archives go to:
      <br>
      Only members subscribed via the mailman list are allowed to post.
      <br>
    </blockquote>
  </body>
</html>

--------------t1LL3Y0m2zEGpXho7ivhnMND--

--===============4565469499305064897==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Haskell-Cafe mailing list -- [email protected]
To (un)subscribe, modify options or view archives go to:
Only members subscribed via the mailman list are allowed to post.
--===============4565469499305064897==--