Stream: beginners

Topic: Best practices for functions that accept multiple types


view this post on Zulip Ruby (Aug 21 2025 at 20:14):

I'm trying to create a concat function that can accept either a string or a function as its second argument. Here's what I have:

main! = |_args|
    Stdout.write!? ("hey" |> concat(Fn Ansi.cr))
    Ok({})

concat = |str, str_or_thunk|
    when str_or_thunk is
        Str s -> Str.concat(str, s)
        Fn f -> Str.concat(str, f(""))

This works, but I have a few questions:

  1. Why do I need to explicitly tag functions with Fn? I noticed that Str works as both a tag name and type, but function types like (Str -> Str) can't be used as tag names. Is there a technical reason for this?

  2. Is there a cleaner/more idiomatic way to achieve this in Roc? Coming from other languages, I'm used to function overloading or polymorphic functions. What's the Roc way to handle this pattern?

  3. What's the general preference in the Roc community for cases where you want a function to accept different types? Should I:

My use case is building ANSI escape sequences where sometimes I want to concatenate a literal string and sometimes I want to concatenate the result of a function call (like Ansi.cr which returns carriage return).

Thanks!
p.s. I used ai to help me formulate this, sorry. my brain melts a bit cause it's 10pm

view this post on Zulip Ruby (Aug 21 2025 at 20:16):

Oh. It seems like I need to also use Str as well.
Stdout.write!? ("hey" |> concat(Str "you")

okay, maybe that is not that bad, it looks clear

view this post on Zulip Anton (Aug 22 2025 at 10:42):

  1. If we allowed tag unions without tag names it would add a bunch of complexity. For example, pattern matching with tag names is very simple. Without tag names the type would have to be determined at runtime.

view this post on Zulip Anton (Aug 22 2025 at 12:06):

2+3. I would also use tag unions here. For function overloading we plan on adding static dispatch, but for this case I would probably still use tag unions.


Last updated: Sep 09 2025 at 12:16 UTC