Is it possible to expose type variants without importing into global namespace?

module Size exposing (Size, Maybe, ..etc..)

type Size = ...

type Maybe = Valid Size | Negative

module Main ..etc..
import Size exposing (Size)

case ... of
  Size.Negative -> ...
  Size.Valid measurement -> ...

Since this example doesn’t expose the constructors, we get “never heard of variant Negative”.

import Size exposing (Size,Maybe(..))

This exposes the constructors, and the above code works, but then elsewhere in the Main module:

type MaybeMessage = Maybe String

error: The `Maybe` type needs 0 arguments, but I see 1 instead

Which means it assumes I’m talking about Size.Maybe. But I basically always explicitly name the module for anything exposed in it to keep my namespaces clean. So if I want Size.Maybe I’ll call it that, if I want Size.Negative constructor I’ll call that that as well.

Is it possible to expose import those constructors without dumping the Size.Maybe type into global namespace?

import Size exposing (Size,Maybe(..) as Size.Maybe)

for example does not work. :o

You don’t have to expose the Maybe type in Main’s import. If you just write

import Size exposing (Size)

it should work.

1 Like
module Size exposing (Size, Maybe(..))

type Size = ...

type Maybe = Valid Size | Negative


module Main exposing (main)

import Size exposing (Size)

... _ = Size.Negative

This works for me (v0.19). Are you sure your module name is Size and not Dir1.Dir2.Size.
Then it would be:

module Main exposing (main)

import Dir1.Dir2.Size as Size exposing (Size)

You can add import Maybe and have

type Maybe message = Maybe.Maybe String

I think that should work.

Separately, I think using the name Maybe for your module might be misleading to anyone who comes to read your code, including you, a year from now since it’s a core type. Instead of marking it as Valid, something like

parse : ? -> Result Error Size
parse input =
    -- parse to either a Size or an error

Not certain this fits with your code but generally I recommend trying to parse a value instead of separately mark something as valid/invalid. If you need to keep some type denoting whether or not it’s valid, then I’d go with something like

type Valid = Valid Size | Invalid
1 Like

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