Using Maybe.withDefault as a type

Hi guys :smiley: , I’m trying to use Elm Maybe withdefault as a type but it is not working correctly as I expected.

What I’m trying to do?
I’m trying to create a base url that concat 2 parameters and return a complete url as result.

base: String -> (Maybe.withDefault "" String) -> String
base version path =
    String.concat ["https://127.0.0.1:8000/api/", version, "/models/", path]

if the path is provided I need to return the url with the path provided, other wise I’ll just do nothing with the path (e.g: not required parameter ).

i’m getting the error bellow. I’m trying to figure out what I’m doing wrong. can you guys give me a help please?

./src/Main.elm
Error: Compiler process exited with error Compilation failed
Compiling ...-- PROBLEM IN TYPE ANNOTATION -------------------------------------- src/Api.elm

I was partway through parsing the `base` type annotation, but I got stuck here:

3| base: String -> (Maybe.withDefault "" String) -> String
                   ^
I was expecting to see a type next. Try putting Int or String for now?

Hi! You cannot use Maybe.withDefault in a type annotation. In general, you can’t call functions in type annotations.

If I understand you correctly, you want to build a URL where the last segment can be optional. If so, one way of modelling that is by using Maybe String. Then you can use Maybe.withDefault "" to handle Nothing – which you seem to be on track towards, but got stuck with where to put that Maybe.withDefault:

base : String -> Maybe String -> String
base version path =
    String.concat ["https://127.0.0.1:8000/api/", version, "/models/", path |> Maybe.withDefault ""]

Some extra thoughts:

You could also go with just a String, since you can pass in an empty string to get the same result:

base : String -> String -> String
base version path =
    String.concat ["https://127.0.0.1:8000/api/", version, "/models/", path]

But then it’s not as clear anymore that path can intentionally be missing. :man_shrugging:

When you have multiple parameters with the same type it can be nice to use a record to make mixups harder:

base : { version: String, path : String } -> String
base { version, path } =
    String.concat ["https://127.0.0.1:8000/api/", version, "/models/", path]

You could also use Url.Builder.absolute if you feel fancy.

5 Likes

Thank very much for your explanation :smiley: , I did the modifications and it worked great fully. I’ll take a loot at the Url.Builder too :smiley: .

3 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.