Comment

Comment by greener_grass

The intuitive definition of NonEmptyList is:

    type NonEmptyList<'t> = 't * 't list
But this cannot be passed to any function that expects a List<'t>. This is odd though, since intuitively, all non-empty lists are lists.

See Rich Hickey's "Maybe Not" talk

OOP solution is to use inheritance. Typical ML solution is to use type-classes.

F# sits in an awkward middle-ground where neither is a perfect fit.

I believe that dependently-typed languages solve this more elegantly.

There's also the syntactic inconvenience of wrapping at construction, where in theory the compiler could figure it out for you.

For example:

    let xs = 1 :: 2 :: 3 :: []
Here xs is non-empty, but we must tell the compiler:

    let xs = 1, 2 :: 3 :: []
TypeScript does a better job here (although a great cost!)

What you end up with is massive code duplication or lots of extra function calls:

   xs
   |> NonEmptyList.toList
   |> List.map (fun x -> x + 1)
   |> NonEmptyList.unsafeFromList
(I say this all as someone who really likes F#)

Discussion

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton