Stream: beginners

Topic: Record builders without `<-`


view this post on Zulip Aurélien Geron (Aug 03 2026 at 03:40):

I'm trying to migrate the RecordBuilder example but the <- operator no longer exists so I'm not sure what to do. Should I drop this example for now (e.g., if there's a plan to add the <- operator in the future) or should I just implement a desuraged version?

view this post on Zulip Luke Boswell (Aug 03 2026 at 04:16):

Record builders look different now

view this post on Zulip Luke Boswell (Aug 03 2026 at 04:17):

Here is an example

character_generator : Str -> Random.Generator(Character)
character_generator = |name| {
    d20 = Random.bounded_u8(1, 20)
    lucky_generator = Random.map(Random.bounded_u8(1, 20), |roll| roll == 20)

    {
        name: Random.static(name),
        strength: d20,
        agility: d20,
        hit_points: Random.bounded_u8(8, 16),
        lucky: lucky_generator,
    }.Random
}

view this post on Zulip Luke Boswell (Aug 03 2026 at 04:17):

Any nominal type with a map2 can participate automatically

view this post on Zulip Richard Feldman (Aug 03 2026 at 04:18):

@Aurélien Geron we just changed the syntax! See https://github.com/lukewilliamboswell/weaver for an example - you basically make a nominal type with a map2 method

view this post on Zulip Richard Feldman (Aug 03 2026 at 04:18):

ha, Luke beat me to it :laughing:

view this post on Zulip Luke Boswell (Aug 03 2026 at 04:18):

Richards example is better though :shrug:

view this post on Zulip Aurélien Geron (Aug 03 2026 at 04:19):

Cool, thanks to both of you! :+1:

view this post on Zulip Aurélien Geron (Aug 03 2026 at 23:02):

It took me a while, but I finally got a working minimal example. I'll post it here in case anyone else needs a simple example:

EnvReader(a) : Dict(Str, Str) -> Try(a, [MissingEnv(Str)])

Reader :: {}.{
    map2 : EnvReader(a), EnvReader(b), (a, b -> c) -> EnvReader(c)
    map2 = |reader_a, reader_b, combine|
        |env| {
            a = reader_a(env)?
            b = reader_b(env)?
            Ok(combine(a, b))
        }
}

read_str : Str -> EnvReader(Str)
read_str = |key| {
    |env| {
        env.get(key).map_err(|_| MissingEnv(key))
    }
}

main! = |_| {
    app_config = {
        host: read_str("HOST"),
        port: read_str("PORT"),
    }.Reader
    env = Dict.from_list([
        ("HOST", "127.0.0.1"),
        ("PORT", "8000"),
        ("FOO", "123"),
        ("BAR", "456"),
    ])
    dbg app_config(env)
    Ok({})
}

Last updated: Aug 12 2026 at 12:35 UTC