Does a function exists that checks the Type of a variable in an Elm? For example (repl):
numberTwo = 2
.....
returnType numberTwo
"number" : String
The motivation for this is that when you are using Signal.map[n]
the situation usually arises that not all of the arguments to the function to be applied are Signals - they then usually have to be 'promoted' to Signals using Signal.constant
- if I could check the type of such arguments, I could create a function Signal.allSigMap[n]
that would turn such arguments into Signals automatically.
So
Signal.map2 grandFatherClock clockSignalElement (Signal.constant cabinetElement)
becomes
Signal.allSigMap2 grandFatherClock clockSignalElement cabinetElement
Could be bad practice though. Please let me know.
I'll respond first to your intention to use
returnType
as a way of promoting types as necessary toSignal
. That would entail thatreturnType
or some other function along the way actually return a type rather than aString
since there's no other way to make the type checker happy.Such a function does not exist and cannot exist within Elm as it stands today. What you're asking for is something that can inspect the type of a value compile time and then run a function on that type.
To see why this is radically different from anything that currently exists in Elm, let's assume such a function exists.
We're immediately confronted with the first question of what exactly is the type of
returnType
. Let's handwave this and say we have a type for all types calledType
(which has its own set of logical problems we'll leave aside).How do we actually use this function? Presumably it'll be able to go in the type signature since it's returning a type.
Now that is a type signature completely different from everything else in Elm. There's a numeric literal (and a function)! All of a sudden you can start to write things like this.
That is way beyond what Elm's type system can do. That sort of (exciting and powerful) type level and value level mixing is known as dependent typing and no mainstream fully dependently typed languages exist; the closest things to mainstream are probably Coq, Agda, Idris, and ATS which are all fairly obscure.
As for the question as literally stated of having a function
returnType : a -> String
that prints out a string representing the type of a value, that's also not possible in Elm, although for other reasons. Such a function (which is something whose application occurs at runtime) must be able to reconstruct type information about a runtime value, but runtime values of Elm are just Javascript values; they've been stripped of their Elm types. You'll have to either reconstruct the original Elm type from the Javascript value (not always possible as different types can end up as the same Javascript value) or have special compiler support.In the case of the Elm REPL, the latter is chosen. The whole REPL is written in Haskell and takes of advantage of how Elm types are implemented in the Haskell runtime.
This is not possible (and not desirable, I would argue) due to Type Erasure (https://en.wikipedia.org/wiki/Type_erasure). Because everything in elm must be well typed, the compiler can verify all the types line up at compile time. Once that is done, it can safely remove all type information from the compiled code that actually gets run. This actually makes the code more efficient, as at runtime no type information (or runtime type checks, like you may be familiar with in typical javascript code) needs to be carried around with all your values.
I believe it's unlikely runtime type introspection would ever be added to languages like elm. Needing to check a type at runtime is a codesmell for poorly designed code.
I also wondered why no instanceOf or typeOf in Elm. Then going through docs thoroughly for deeper understanding of FRP it became clear! You should know the shape of your data at all times. In order to do so using case...of pattern with Elms Tagged Unions you should be able to access your desired values by filtering your known types. Caveat, all branches of case...of must be of the same type, but that doesn't preclude you from using a tuple with superset of of all your known types with dummy sentinel values to allow you access your desired type.
See code below for illustration:
Assumptions:
1.Your desired types are tagged when used
2.Using sentinel values
There's no such function in the core libraries. You'd need to write your own, which is half-done for you because you can reverse engineer elm-repl.