What you are looking at is what we call a Custom Type. They can be recursive, but this one is not.
A way to read it goes something like this. type Avatar is saying I am creating a new type called "Avatar’. = Avatar (Maybe String) is saying a few things. First it is saying we only have one “variant”. Next it is saying what the name of the type constructor is (in this case its Avatar but it does not need to match the type name). And lastly it is saying that Avatar “holds” (Maybe String)
Id recommended checking out the link to Custom Types above, and also tossing that type into elm repl and playing around with it .
I would read it like "type Avatar has a constructor called Avatar that takes Maybe String as an argument.
So it’s similarly to object-oriented languages, where the class constructor has the same name as the class. In java I would write: Avatar avatar = new Avatar(stringOrNull)
so if i understand correctly here, type definition is collection of functions that result in that type. In other words all the way in which type can be constructed.
in this case it would be only one function (Maybe String) -> Avatar, however i still have a problem with "visualizing " shape of Avatar.
my formal FP is obviously not that strong so i would appreciate very much if someone can point to some resources where i could better understand mechanism, how is elm tracking which constructor is used and such.
Yes. exatly. Though it does not have to be functions.
Let’s look at Bool for a sec:
type Bool
= True
| False
So Bool can either be True or False. (The symobl | is read as “or”) That’s the structure of Bool.
Where as for Maybe a the definiton is
type Maybe a
= Just a
| Nothing
So the structure behind it is either Nothing, or (Just something).
Just itself is also a function. Just:a -> Maybe So depending on how you look on it. its either “How do i construct this type?” or “What shape can this type be?”.
Now back to the Avatar.
type MyAvatar
= AvatarByName (Maybe String)
So Avatar is defined by its name. So the structure of the Avatar is its name.
In other languages types are collections of things, usually other types and from this is seems that in elm one construct the type in “reverse”, meaning you declare pathways in which you arrive to the type.
I haven’t seen an actual recursive type yet in this thread, so thought I would give an example of one whilst hopefully not causing any confusion… Recursive types are very useful for building data structures.
You could define your own list type like this:
type MyList a
= Nil
| Cons a (MyList a)
Note that the type itself (MyList) appears in constructor argument position under Cons.
Also worth noting that you can only make recursive types in Elm, and you cannot make a recursive type alias:
type alias MyList a =
{ cons : Maybe (a, MyList a) }
-- ALIAS PROBLEM ---------------------------------------------------------- REPL
This type alias is recursive, forming an infinite type!
2| type alias MyList a =
^^^^^^
When I expand a recursive type alias, it just keeps getting bigger and bigger.
So dealiasing results in an infinitely large type! Try this instead:
type MyList a =
MyList
{ cons : Maybe ( a, MyList a ) }
Hint: This is kind of a subtle distinction. I suggested the naive fix, but I
recommend reading <https://elm-lang.org/0.19.1/recursive-alias> for ideas on how
to do better.