Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

62 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

list1

Striving toward a better interface for NonEmpty.

If you know it's not null, you have at least one Sole thing, or something & some other things!

data List1 x = x :| [x]
  deriving (...)

-- | Match a singleton 'List1'.
pattern Sole :: x -> List1 x
pattern Sole x = x :| []

-- | Match a 'List1' of length at least 2.
pattern (:||) :: x -> List1 x -> List1 x
pattern x :|| y <- (x :| (list1 -> Just y))
  where
    x :|| ~(y :| ys) = x :| (y : ys)

{-# COMPLETE Sole, (:||) #-}

-- | Isomorphic to '(:|)', but instead with a 'Maybe' 'List1'.
pattern (:?) :: x -> Maybe (List1 x) -> List1 x
pattern x :? y <- (x :| ~(list1 -> y))
  where
    x :? y = maybe (Sole x) (x :||) y

{-# COMPLETE (:?) #-}

list1 :: [x] -> Maybe (List1 x)
list1 = \case
  [] -> Nothing
  x : xs -> Just (x :| xs)

These patterns made writing a lot of the definitions in this module easier, and generally makes working with the cases of a NonEmpty list much more ergonomic.

This module also offers some implementations of NonEmpty functions implemented using these patterns. Exact feature parity with Data.List is not the goal of this package. The intent is to explore the design space: many of the functions that may delete items return a Maybe (List1 x), which is in turn made less unwieldy by having the (:?) bidirectional pattern.

About

Lists that are not null.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages