Interestingly, dynamic languages which make use of symbols (Ruby, Elixir, Common Lisp) probably fall closer to Haskell than Python or TS. Elixir example:
String literals are structural types which are way more expressive than regular (Haskell) ADTs, which are nominal types.
In TS in particular, in combination with other features (mapped types), they are equivalent to row polymorphism + whatever Haskell/GHC features enable type families to specialize on constant literal arguments (or you can use atomic types, but that's not structural / open-world)... so pretty advanced.
This is valid TS/Python:
type ABC = "A" |"B" | "C"
type AB = "A" | "B"
const x: AB = "A";
const y: ABC = x;
The equivalent Haskell requires using several extensions.
I know. I literally gave the example of a Python Literal in the post you're replying to. TS too. :)
My overall point is that Haskell's type system is sufficiently expressive (you may not have "A" | "B" | "C", but you do have A | B | C) that there's no obvious remaining use case for string literals, unless you're thinking of typing input by way of expected literals instead of actually parsing it, which is... a choice. :P
My mistake. I see my oversight now. `Either String String` is not equivalent to `String | String`, but to `Left String | Right String`. The same must be done for the C# version.
String literal typing appears to be a common feature of type systems bolted onto dynamic languages:
I assume it exists to compensate for the previous lack of typing, and consequent likelihood of ersatz typing via strings.
It would seem pretty unnecessary in Haskell, where you can just define whatever types you want without involving strings at all:
Of course you'd need a trivial parser, though this is probably a good idea for any string type:
Interestingly, dynamic languages which make use of symbols (Ruby, Elixir, Common Lisp) probably fall closer to Haskell than Python or TS. Elixir example:
Where :yes and :no are memory-efficient symbols, not strings.
String literals are structural types which are way more expressive than regular (Haskell) ADTs, which are nominal types.
In TS in particular, in combination with other features (mapped types), they are equivalent to row polymorphism + whatever Haskell/GHC features enable type families to specialize on constant literal arguments (or you can use atomic types, but that's not structural / open-world)... so pretty advanced.
This is valid TS/Python:
The equivalent Haskell requires using several extensions.
I know. I literally gave the example of a Python Literal in the post you're replying to. TS too. :)
My overall point is that Haskell's type system is sufficiently expressive (you may not have "A" | "B" | "C", but you do have A | B | C) that there's no obvious remaining use case for string literals, unless you're thinking of typing input by way of expected literals instead of actually parsing it, which is... a choice. :P
7 replies →
Thank you for the lecture but I didn’t mean that. I meant `Either String String` is possible in Haskell and not in C# because… C# is strongly-typed.
You're welcome! Knowing is half the battle.
That Haskell snippet is just syntax sugar for Left(string) | Right(string), which is trivial in any language with unions.
Not clear why it would be an improvement over just naming the alternatives something meaningful, but if you're wedded to Left and Right, go for it.
You cant have a `type Foo = String | Strimg` in Haskell either.
But you can have an `Either String String` which is what GP was talking about.
My mistake. I see my oversight now. `Either String String` is not equivalent to `String | String`, but to `Left String | Right String`. The same must be done for the C# version.
1 reply →