Re: Functional design question

Akhra Gannon <[email protected]> Mon, 23 Mar 2026 01:12:55 -0700
Newsgroups gmane.comp.lang.haskell.cafe
Message-ID <CAJoPsuDH9N8mvHU3WUtrpYhaJGZuCOY3bvcfvqndL_chFWn9OQ@mail.gmail.com>
--===============5564877384167359399==
Content-Type: multipart/alternative; boundary="0000000000009d5f72064dac9ae4"

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

On Sun, Mar 22, 2026, 6:15=E2=80=AFPM <[email protected]> wrote:

> Just to verify I understood it correctly:
>
> It's declaring function finalizeConfigValue,
> with two parameters (disregarding currying),
> one is a function a -> Maybe b,
> second is a list of SourceIndex/a tuples;
> result is a Maybe B.
>

correct!

What kind of type is a? A raw parse tree as delivered from the yaml

parser, i.e. a hierarchical blob of Maps, Lists, and Strings for
> terminals? (I decided to configure the parser for "everything is a
> string" because (a) no real need for numbers in my use case and (b)
> possibly YAML has some weird definition of what's number and what's a
> string.)


in that case, it's probably either a string or a list of strings. the
assumption is that you've already dispatched on config keys: the output is
the final canonical value of *one* key; the input list represents
potentially multiple files, repeat definitions within a file, maybe a hard
default for fallback.

the "sorting" would be via custom logic for your SourceIndex type,
indicating which alternative to prefer if there are multiple candidates.
depending on specifics, this may not be versatile enough; just read that
line as "disambiguate between multiple definitions."

What does listToMaybe do?
>

head of list with an option wrapper, so it's safe on empty lists:

listToMaybe [] =3D Nothing
listToMaybe (x:_) =3D Just x

Not sure what the mapMaybe serves. I guess it's dealing with error cases

or some such, but I can't infer what kind of cases that would be and
> what the intended effect it (my lack of Haskell knowledge shows again).


it takes a function with optional return (here, the final value parser) and
maps it to a list, discarding failures and unwrapping the rest.

mapMaybe :: (a -> Maybe b) -> [a] -> [b]

so the whole process is:
- sort by source preference
- parse, discarding failures
- return the first successful parse if one exists (list laziness skips the
rest)

I believe the main block to me understanding such code is that I don't
> know how many parameters a function has - or, in the currying
> perspective, what order a function is.
>

yes, the type annotation is often critical for this. it includes all those
things, which the function head might skip. it's common to read *only*
types on a first pass through unfamiliar code!

I guess I'm going to learn a whole lot here.
> Which is exactly the point, actually :-)


cheers to that! =F0=9F=98=84

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

<div dir=3D"auto"><div><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D=
"gmail_attr">On Sun, Mar 22, 2026, 6:15=E2=80=AFPM  &lt;<a href=3D"mailto:j=
[email protected]" rel=3D"noreferrer noreferrer" target=3D"_blank">jo@durchho=
lz.org</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Just to verif=
y I understood it correctly:<br>
<br>
It&#39;s declaring function finalizeConfigValue,<br>
with two parameters (disregarding currying),<br>
one is a function a -&gt; Maybe b,<br>
second is a list of SourceIndex/a tuples;<br>
result is a Maybe B.<br></blockquote></div></div><div dir=3D"auto"><br></di=
v><div dir=3D"auto">correct!</div><div dir=3D"auto"><br></div><div dir=3D"a=
uto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"=
margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
What kind of type is a? A raw parse tree as delivered from the yaml</blockq=
uote></div></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex">
parser, i.e. a hierarchical blob of Maps, Lists, and Strings for <br>
terminals? (I decided to configure the parser for &quot;everything is a <br=
>
string&quot; because (a) no real need for numbers in my use case and (b) <b=
r>
possibly YAML has some weird definition of what&#39;s number and what&#39;s=
 a <br>
string.)</blockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"au=
to">in that case, it&#39;s probably either a string or a list of strings. t=
he assumption is that you&#39;ve already dispatched on config keys: the out=
put is the final canonical value of *one* key; the input list represents po=
tentially multiple files, repeat definitions within a file, maybe a hard de=
fault for fallback.</div><div dir=3D"auto"><br></div><div dir=3D"auto">the =
&quot;sorting&quot; would be via custom logic for your SourceIndex type, in=
dicating which alternative to prefer if there are multiple candidates. depe=
nding on specifics, this may not be versatile enough; just read that line a=
s &quot;disambiguate between multiple definitions.&quot;</div><div dir=3D"a=
uto"><br></div><div dir=3D"auto"></div><div dir=3D"auto"></div><div dir=3D"=
auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D=
"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
What does listToMaybe do?<br></blockquote></div></div><div dir=3D"auto"><br=
></div><div dir=3D"auto">head of list with an option wrapper, so it&#39;s s=
afe on empty lists:</div><div dir=3D"auto"><br></div><div dir=3D"auto"><div=
 class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"></blockquote></div></=
div><div dir=3D"auto"></div><div dir=3D"auto">listToMaybe [] =3D Nothing</d=
iv><div dir=3D"auto">listToMaybe (x:_) =3D Just x</div><div dir=3D"auto"><b=
r></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex">
Not sure what the mapMaybe serves. I guess it&#39;s dealing with error case=
s</blockquote></div></div><div dir=3D"auto"><div class=3D"gmail_quote"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #c=
cc solid;padding-left:1ex">
or some such, but I can&#39;t infer what kind of cases that would be and <b=
r>
what the intended effect it (my lack of Haskell knowledge shows again).</bl=
ockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto"></div><d=
iv dir=3D"auto"></div><div dir=3D"auto">it takes a function with optional r=
eturn (here, the final value parser) and maps it to a list, discarding fail=
ures and unwrapping the rest.</div><div dir=3D"auto"><br></div><div dir=3D"=
auto">mapMaybe :: (a -&gt; Maybe b) -&gt; [a] -&gt; [b]</div><div dir=3D"au=
to"><br></div><div dir=3D"auto">so the whole process is:</div><div dir=3D"a=
uto">- sort by source preference</div><div dir=3D"auto">- parse, discarding=
 failures</div><div dir=3D"auto">- return the first successful parse if one=
 exists (list laziness skips the rest)</div><div dir=3D"auto"><br></div><di=
v dir=3D"auto"></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex">I believe the main block to me understanding such cod=
e is that I don&#39;t <br>
know how many parameters a function has - or, in the currying <br>
perspective, what order a function is.<br></blockquote></div></div><div dir=
=3D"auto"><br></div><div dir=3D"auto">yes, the type annotation is often cri=
tical for this. it includes all those things, which the function head might=
 skip. it&#39;s common to read *only* types on a first pass through unfamil=
iar code!</div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"=
gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex">
I guess I&#39;m going to learn a whole lot here.<br>
Which is exactly the point, actually :-)</blockquote></div></div><div dir=
=3D"auto"><br></div><div dir=3D"auto">cheers to that! =F0=9F=98=84</div><di=
v dir=3D"auto"></div></div>

--0000000000009d5f72064dac9ae4--

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