HN.zip

Type-checked non-empty strings

42 points by surprisetalk - 23 comments
muglug [3 hidden]5 mins ago
Very cool that the language allows specification of a type in this way.

I added a similar type — “non-empty-string” to a typechecker for PHP, and it’s been adopted widely in the PHP ecosystem. It turns out to be pretty handy, especially when there’s a full type system to support it.

IshKebab [3 hidden]5 mins ago
"Huh never heard of Bellroy... I wonder what they're using Haskell for..."

Turns out it's some kind of bags and accessories brand!

kccqzy [3 hidden]5 mins ago
I bought a leather wallet from them in 2016 and it is still holding up well despite a few loose stitches.
flexagoon [3 hidden]5 mins ago
I've had a Bellroy bag, they're not the most fashionable but super high quality and well thought-out. Just like Haskell code—maybe that's why they like it.
umpalumpaaa [3 hidden]5 mins ago
In the backpack community bellroy is often seen as “meh”. Eg. they frequently don’t live up to the guarantees they give and to the quality they promise. Also overpriced.
qbane [3 hidden]5 mins ago
I pondered for a while, it IS the company I used to know
ambicapter [3 hidden]5 mins ago
I once saw a job ad for a company selling a horoscope app that required Haskell. An unusual conjunction for sure.
saithound [3 hidden]5 mins ago
Astrology and Haskell are quite similar in that both are much much easier to do if you have a math degree.
recursive [3 hidden]5 mins ago
Ok, I'll bite. How does a math degree help with astrology?
saithound [3 hidden]5 mins ago
The starting point of casting a horoscope is calculating the apparent locations (this means "where you would have seen them had you looked up there and then") of a whole bunch of celestial objects at the time and place where a particular person was born.

You won't (write software to) do that without knowing a whole bunch of linear algebra and ODEs.

The fortune-telling part is not what needs the math degree.

tialaramex [3 hidden]5 mins ago
Are you sure? I can see for Astronomy that's a branch of physics so sure, there's loads of tricky practical mathematics so if you're bad at mathematics you'll get stuff wrong, but surely for Astrology since it's just bullshit anyway you don't need to do mathematics as it wouldn't make a difference?
saithound [3 hidden]5 mins ago
A horoscope is a fine mixture of fortune-telling bullshit and verifiable astronomical facts. The latter have the form of "where the celestial bodies could be seen at the hour of the client's birth", or "does Jupiter currently appear to be moving forward or backward in the sky".

The average Visual Basic programmer and the world's best mathematician are going to be about equally good at writing the fortune-telling part, but the mathematician will have a much easier time getting the factual part right.

gib444 [3 hidden]5 mins ago
Using Haskell for a horoscope app is like hiring a mathematician to read tea leaves
saithound [3 hidden]5 mins ago
Astrology is a mixture of factual verifiable information (such as apparent positions of celestial bodies at the time and location a certain person was born) and random baseless divinations.

The "whale" users who account for a disproportionately large percentage of an astrologer's revenue tend to know the factual information surrounding their birth fairly well. An app/astrologer who doesn't get these facts right, even for a handful of clients, will get a bad reputation fairly quickly.

I reckon the same principle would hold in cultural bubbles where reading tea leaves is a customary means of divination. If the client recognizes recognize black tea, but the fortuneteller insists it is rooibos, there won't be much trust in the rest of the prophecy.

Advertising that the horoscope shop uses Haskell is actually a solid business idea. It pre-filters for the sort of dev who will be able to do the math.

ivanjermakov [3 hidden]5 mins ago
Language is not mentioned in a title, so my first thought was about TypeScript type wizardry. Turns out it's as simple as `Exclude<string, "">`.

https://www.typescriptlang.org/docs/handbook/utility-types.h...

Edit: nevermind, LLM fooled me.

antipurist [3 hidden]5 mins ago
It's simple, and it doesn't work as `Exclude` only applies to union types. For type `string` it just returns the same type `string`.
phpnode [3 hidden]5 mins ago
yup, it's not possible to do it safely with a simple unparameterised type: https://www.typescriptlang.org/play/?#code/C4TwDgpgBAcg9gOwK...
ralferoo [3 hidden]5 mins ago
It is very much mentioned in the article title and the first sentence. It's just HN that's truncated the title.
Cthulhu_ [3 hidden]5 mins ago
Speaking of TS, there's stuff in there for typing strings / string formats: https://www.typescriptlang.org/docs/handbook/2/template-lite...
nvme0n1p1 [3 hidden]5 mins ago
Daily reminder that TypeScript's type checker is not sound.

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAcg9gOwK...

blue_pants [3 hidden]5 mins ago
It is true, but it wasn't meant to be sound, so it's okay.

You can do this trick for type-checking emptiness of string literals

https://www.typescriptlang.org/play/?jsx=0#code/C4TwDgpgBAsg...

recursive [3 hidden]5 mins ago
Daily reminder that the unsoundness in Typescript's type checker is a practical compromise applied to a language that was never designed to be type checked in this way, and furthermore that many developers feel that it strikes a good balance between formal correctness and practical usability.
IceDane [3 hidden]5 mins ago
This example is not only wrong for what you intend to demonstrate but even if it wasn't, it's not problematic. In typescript the proper way to do this is using branded types and exporting only the safe constructor, making anyone who wants to violate the invariant go out of their way, which is no different from the situation in any number of programming languages or scenarios.

  declare const brand: unique symbol;
  type NonEmptyString = string & { readonly [brand]: 'NonEmptyString' };

  // the ONLY non-cast way to produce one
  export function nonEmptyString(s: string): NonEmptyString | undefined {
    return s.length > 0 ? (s as NonEmptyString) : undefined;
  }

  export type { NonEmptyString };