Re: Functional design question

Akhra Gannon <[email protected]> Sun, 22 Mar 2026 17:07:50 -0700
Newsgroups gmane.comp.lang.haskell.cafe
Message-ID <CAJoPsuDpXVaox+CRpv2EQjPs6Yka+GbDjweuWqBEf1JD026B-g@mail.gmail.com>
--===============2482828950825417300==
Content-Type: multipart/alternative; boundary="000000000000da44ca064da5d37c"

--000000000000da44ca064da5d37c
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

honestly, the way you've laid it out looks perfectly reasonable to me! it
generally follows the principle ot "parse, don't validate" laid out here:
https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/

the only core change I might make is to remove the payload from ConfigData
and use a tuple of (SourceIndex, a) instead, so you can operate on one
without examining the other. this lets you do all the source-related
analysis with monomorphic code; and in cases where the final payload type
is unchanged, you can just discard the tuple wrapper to finalize.

at the top level, for each final-config item I'd imagine the process would
(in Haskell) look something like:

finalizeConfigValue
  :: (a -> Maybe b)
  -> [(SourceIndex, a)]
  -> Maybe b
finalizeConfigValue valueParser
  =3D listToMaybe
  . mapMaybe (valueParser . snd)
  . sortOn fst

with an Ord instance on SourceIndex, and the Maybe output representing
failure of all candidates to parse (you could also use defaulting and/or
exceptions)


On Sun, Mar 22, 2026, 4:10=E2=80=AFPM Joachim Durchholz <joachim@durchholz.=
org>
wrote:

> Hi all,
>
> 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.
>
> Bird's eye view:
>
> Java everybody knows (I don't like it either, no worries), Vavr is a -
> to my eyes - pretty nice functional library, https://docs.vavr.io/ for
> details if you're actually interested.
> 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.
>
> 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.
> 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.
>
> Things I'm undecided about:
>
> a) Data type variations
> During the configuration phase, I need to carry information about where
> some configuration item came from (its ("context", usually file, line
> number, column number).
> In the processing phase, configuration is considered final and
> error-free, so context is not needed (that's a done design decision).
> 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=
)
>    DirectoryConfig {
>      ConfigData<Path> path
>      ConfigData<String> title
>      ...
>    }
>    data ConfigData<a> {
>      String fileName
>      int lineNumber
>      int columnNumber
>      a value
>    }
> but in the processing phase I don't want my config objects polluted with
> context, so I want
>    DirectoryConfig {
>      Path path
>      String title
>      ...
>    }
> 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).
> So... how would one do such a thing in a functional language?
> 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.
>
> 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?
>
> 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.
>
> Regards,
> Jo
> _______________________________________________
> 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.
>

--000000000000da44ca064da5d37c
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto">honestly, the way you&#39;ve laid it out looks perfectly =
reasonable to me! it generally follows the principle ot &quot;parse, don&#3=
9;t validate&quot; laid out here:=C2=A0<a href=3D"https://lexi-lambda.githu=
b.io/blog/2019/11/05/parse-don-t-validate/">https://lexi-lambda.github.io/b=
log/2019/11/05/parse-don-t-validate/</a><div dir=3D"auto"><br></div>the onl=
y core change I might make is to remove the payload from ConfigData and use=
 a tuple of (SourceIndex, a) instead, so you can operate on one without exa=
mining the other. this lets you do all the source-related analysis with mon=
omorphic code; and in cases where the final payload type is unchanged, you =
can just discard the tuple wrapper to finalize.<div dir=3D"auto"><br></div>=
<div dir=3D"auto">at the top level, for each final-config item I&#39;d imag=
ine the process would (in Haskell) look something like:</div><div dir=3D"au=
to"><br></div><div dir=3D"auto">finalizeConfigValue</div><div dir=3D"auto">=
=C2=A0 :: (a -&gt; Maybe b)</div><div dir=3D"auto">=C2=A0 -&gt; [(SourceInd=
ex, a)]</div><div dir=3D"auto">=C2=A0 -&gt; Maybe b</div><div dir=3D"auto">=
finalizeConfigValue valueParser</div><div dir=3D"auto">=C2=A0 =3D listToMay=
be</div><div dir=3D"auto">=C2=A0 . mapMaybe (valueParser . snd)</div><div d=
ir=3D"auto">=C2=A0 . sortOn fst</div><div dir=3D"auto"><br></div><div dir=
=3D"auto">with an Ord instance on SourceIndex, and the Maybe output represe=
nting failure of all candidates to parse (you could also use defaulting and=
/or exceptions)<br><div dir=3D"auto"><br><div dir=3D"auto"><br></div><div d=
ir=3D"auto"><div dir=3D"auto"><div dir=3D"auto"><div dir=3D"auto"><div clas=
s=3D"gmail_quote gmail_quote_container" dir=3D"auto"><div dir=3D"ltr" class=
=3D"gmail_attr">On Sun, Mar 22, 2026, 4:10=E2=80=AFPM Joachim Durchholz &lt=
;<a href=3D"mailto:[email protected]">[email protected]</a>&gt; wro=
te:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex">Hi all,<br>
<br>
I have some design questions - not for Haskell but for the Java+Vavr <br>
combo, but I am about to dip my toes into actual work in a functional <br>
manner, as far as that is possible, and I thought I might as well go for <b=
r>
the community that&#39;s best subscribed to a purely functional style.<br>
<br>
Bird&#39;s eye view:<br>
<br>
Java everybody knows (I don&#39;t like it either, no worries), Vavr is a - =
<br>
to my eyes - pretty nice functional library, <a href=3D"https://docs.vavr.i=
o/" rel=3D"noreferrer noreferrer" target=3D"_blank">https://docs.vavr.io/</=
a> for <br>
details if you&#39;re actually interested.<br>
I want to leverage Vavr to get a Java program to be as Haskell-ish as is <b=
r>
reasonable; that&#39;s not going to be much by a Haskeller&#39;s standards,=
 <br>
but... baby steps.<br>
<br>
Application is a simple command-line thing: Read configuration from <br>
command line and configuration file, emit diagnostics about any errors <br>
in the config, then process.<br>
I want the configuration processing to be as functional as reasonable, <br>
given the constraints. However, I&#39;m undecides about many things, no <br=
>
doubt because I simply don&#39;t know the best design patterns, and it&#39;=
s <br>
frustrating to see multiple options and not knowing which ones will <br>
paint me into a corner and which ones will not.<br>
<br>
Things I&#39;m undecided about:<br>
<br>
a) Data type variations<br>
During the configuration phase, I need to carry information about where <br=
>
some configuration item came from (its (&quot;context&quot;, usually file, =
line <br>
number, column number).<br>
In the processing phase, configuration is considered final and <br>
error-free, so context is not needed (that&#39;s a done design decision).<b=
r>
I could carry context information into the processing phase, but it&#39;s <=
br>
going to be awkward: Say, we have the following types (forgive the most <br=
>
un-Haskellish pseudo syntax but I don&#39;t dare to use Haskell style <br>
because I&#39;d almost certainly get that wrong and provoke misunderstandin=
gs)<br>
=C2=A0 =C2=A0DirectoryConfig {<br>
=C2=A0 =C2=A0 =C2=A0ConfigData&lt;Path&gt; path<br>
=C2=A0 =C2=A0 =C2=A0ConfigData&lt;String&gt; title<br>
=C2=A0 =C2=A0 =C2=A0...<br>
=C2=A0 =C2=A0}<br>
=C2=A0 =C2=A0data ConfigData&lt;a&gt; {<br>
=C2=A0 =C2=A0 =C2=A0String fileName<br>
=C2=A0 =C2=A0 =C2=A0int lineNumber<br>
=C2=A0 =C2=A0 =C2=A0int columnNumber<br>
=C2=A0 =C2=A0 =C2=A0a value<br>
=C2=A0 =C2=A0}<br>
but in the processing phase I don&#39;t want my config objects polluted wit=
h <br>
context, so I want<br>
=C2=A0 =C2=A0DirectoryConfig {<br>
=C2=A0 =C2=A0 =C2=A0Path path<br>
=C2=A0 =C2=A0 =C2=A0String title<br>
=C2=A0 =C2=A0 =C2=A0...<br>
=C2=A0 =C2=A0}<br>
No idea how to deal with that. I&#39;d use code generation in Java I guess,=
 <br>
but that&#39;s horribly inelegant and complicated to set up (no, I don&#39;=
t <br>
particularly like Java, it&#39;s just what I&#39;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 <b=
r>
kind of stuff, but I&#39;m more-or-less tied to Java + functional libraries=
, <br>
so I&#39;ll have to stick with the more basic approaches most likely. <br>
Besides, even if I did Haskell, I&#39;d want to avoid the advanced stuff <b=
r>
until I get confident in the basics.<br>
<br>
TL;DR: I have a deeply nested configuration data structure where each <br>
field has a &quot;context&quot;, i.e. the place it came from; how to I make=
 it so <br>
that the context is available during configuration evaluation but is <br>
unavailable in the later processing phase?<br>
<br>
I hope this is understandable; it&#39;s really hard to do that when you <br=
>
don&#39;t even know enough to ask the questions precisely enough.<br>
<br>
Regards,<br>
Jo<br>
_______________________________________________<br>
Haskell-Cafe mailing list -- <a href=3D"mailto:[email protected]" ta=
rget=3D"_blank" rel=3D"noreferrer">[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></div></div></div></div></div></div></div></div>

--000000000000da44ca064da5d37c--

--===============2482828950825417300==
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.
--===============2482828950825417300==--