If the choice is between adding List.singleton or not, I vote for adding it.
The robot-ninja-monkey-gorilla-whathaveyou operator always causes me to do a double take, and I'm actually displeased with there being special syntax for `List` alone - I don't see any special syntax for `Set/Map`, or `Either`, which is even more fundamental, and on pair with tuples.
But I'd actually prefer a singleton method. It seems a frequent point of debate is single-element-intent vs polymorphic-ness. I'd like to note that they're not mutually exclusive (whether we end up with best of both worlds or worst is up for discussion).
When I think of a container of x, I think of some data structure with x values inside. Now, they need to be stored/organized/structured *somehow*, and there's a distinction here:
- some containers require each element to be paired with it's index/key/location (e.g. Map, HashMap, (->))
- some containers build the entire structure based on a single value/dictionary which can be known ahead of time, before any values are provided (e.g. Set uses Ord, HashSet uses Hashable, List trivially uses the empty constraint ())
For the second case, we can conceive of a fromList function (left and right inverse of toList), which then gives us singleton = fromList . (:[])
Something like:
class Unfoldable1 c a where
fromNonEmpty :: NonEmpty a -> c a
singleton :: a -> c a
singleton = fromNonEmptyList . (:|[]) -- moustached gorilla operator
-- constrast with Foldable
class Unfoldable1 c a => Unfoldable c a where
fromList :: [a] -> c a
unfoldr :: (b -> Maybe (a, b)) -> b -> c a
unfoldr f = fromList . Data.List.unfoldr f
instance Unfoldable1 [] a where
fromNonEmpty = toList
instance Unfoldable [] a where
fromList = id
instance Unfoldable1 NonEmpty a where
fromNonEmpty = id
instance Ord a => Unfoldable1 Set a where
fromNonEmpty = fromList . toList
instance Ord a => Unfoldable Set a where
fromList = Set.fromList
instance (Eq a, Hashable a) => Unfoldable1 HashSet a where
fromNonEmpty = fromList . toList
instance (Eq a, Hashable a) => Unfoldable HashSet a where
fromList = HashSet.fromList