Stream: beginners

Topic: Working with results


view this post on Zulip Tobias Steckenborn (Sep 12 2024 at 17:35):

Given I've got a string that looks like this
"123x123x123
234x123x987
567x987x123"

I'd like to transform this into something like [{a: 123, b: 123, c: 123}, {a: 234, b: 123, c: 987}, {a: 567, b: 987, c: 123}].

Without access to the lsp right now, I'm somehow confused.

I'd have assumed something like:

    inputDetails =
        inputs
        |> Str.split "\n"
        |> List.dropIf Str.isEmpty
        |> List.map parseLine

parseLine = \singleLine ->
    lineParts = Str.split singleLine "x"
    if List.len lineParts == 3 then
        a = List.get? lineParts 0 |> Str.toI8
        b = List.get? lineParts 1 |> Str.toI8
        c = List.get? lineParts 2 |> Str.toI8
        Ok { a, b, c }
    else
        Err InvalidInputFormat

Yet this is a list of results with properties of a result type which I can't seem to use in further functions requiring numbers. What would I need to do in order to work further with these properties?

view this post on Zulip Sam Mohr (Sep 12 2024 at 18:00):

You'll be looking for mapTry, of type List elem, (elem -> Result ok err) -> Result (List ok) err

view this post on Zulip Sam Mohr (Sep 12 2024 at 18:04):

I'd recommend something like:

inputDetails =
    inputs
    |> Str.split "\n"
    |> List.dropIf Str.isEmpty
    |> List.mapTry parseLine

parseLine = \line ->
    parsedNums =
        line
        |> Str.split "x"
        |> List.mapTry Str.toI8

    when parsedNums is
        Ok [a, b, c] -> Ok { a, b, c }
        Ok _ -> Err WrongAmountOfNums
        Err InvalidNumStr -> Err InvalidNum

This could help avoid the repetition in parseLine

view this post on Zulip Tobias Steckenborn (Sep 12 2024 at 18:30):

The output of that would be Result (List { height : I8, length : I8, width : I8 }) [InvalidNum, WrongAmountOfNums] right? Given I'd need to pass this into a further function, just calling
` |> List.map \element -> someFunction element.a element.b element.c wouldn't work, right?

view this post on Zulip Sam Mohr (Sep 12 2024 at 18:37):

@Tobias Steckenborn yes, we can't with the above code just use inputDetails, as errors have potentially occurred. My code changes inputDetails from List (Result { ... } [...]) to Result (List { ... }) [...], but there is still a Result being returned

view this post on Zulip Sam Mohr (Sep 12 2024 at 18:38):

If you want to access the values inside, you could either put a question mark on |> List.mapTry? parseLine to propagate the potential error up to the result of the function these variables exist within, or call something like |> Result.withDefault [] to handle the result in-place.

view this post on Zulip Sam Mohr (Sep 12 2024 at 18:39):

Otherwise, there's not much to be done while the Result is as-of-yet "wrapped" around the useful value (that may or may not exist).

view this post on Zulip Sam Mohr (Sep 12 2024 at 18:43):

After that point, you could do what you're suggesting:

inputDetails =
    inputs
    |> Str.split "\n"
    |> List.dropIf Str.isEmpty
    |> List.mapTry? parseLine
    |> List.map \element -> someFunction element.a element.b element.c

# ALTERNATIVELY

inputDetails =
    inputs
    |> Str.split "\n"
    |> List.dropIf Str.isEmpty
    |> List.mapTry parseLine

mappedDetails =
    inputDetails?
    |> List.map \element -> someFunction element.a element.b element.c

view this post on Zulip Tobias Steckenborn (Sep 13 2024 at 15:15):

Are you sure that the alternative version should work?

I'm getting:

UNRECOGNIZED NAME

Nothing is named `inputDetails` in this scope.

2024-09-13-at-17.15.102x.png


Last updated: Jul 06 2025 at 12:14 UTC