(.using
  [library
   [lux "*"
    ["$" documentation {"+" documentation:}]
    [control
     ["<>" parser
      ["<[0]>" code]]]
    [data
     ["[0]" text {"+" \n}
      ["%" format {"+" format}]]]
    [macro
     [syntax {"+" syntax:}]
     ["[0]" code]
     ["[0]" template]]]]
  [\\library
   ["[0]" /]])

(documentation: /.mixes
  ""
  [(mixes f init inputs)])

(documentation: /.reversed
  ""
  [(reversed xs)])

(documentation: /.only
  "A list with only values that satisfy the predicate."
  [(only keep? xs)])

(documentation: /.partition
  "Divide the list into all elements that satisfy a predicate, and all elements that do not."
  [(partition satisfies? list)])

(documentation: /.pairs
  "Cut the list into pairs of 2."
  [(pairs list)])

(documentation: /.split_at
  ""
  [(split_at n xs)])

(documentation: /.split_when
  "Segment the list by using a predicate to tell when to cut."
  [(split_when predicate xs)])

(documentation: /.sub
  "Segment the list into sub-lists of (at most) the given size."
  [(sub size list)])

(documentation: /.repeated
  "A list of the value x, repeated n times."
  [(repeated n x)])

(documentation: /.iterations
  "Generates a list element by element until the function returns .#None."
  [(iterations f x)])

(documentation: /.one
  ""
  [(one check xs)])

(documentation: /.all
  ""
  [(all check xs)])

(documentation: /.example
  "Yields the first value in the list that satisfies the predicate."
  [(example predicate xs)])

(documentation: /.interposed
  "Puts a value between every two elements in the list."
  [(interposed sep xs)])

(documentation: /.size
  ""
  [(size list)])

(documentation: /.item
  "Fetches the element at the specified index."
  [(item i xs)])

(documentation: /.sorted
  "A list ordered by a comparison function."
  [(sorted < xs)])

(documentation: /.empty?
  ""
  [(empty? xs)])

(documentation: /.member?
  ""
  [(member? eq xs x)])

(template [<name> <doc>]
  [(documentation: <name>
     <doc>)]

  [/.head "Yields the first element of a list."]
  [/.tail "For a list of size N, yields the N-1 elements after the first one."]
  )

(documentation: /.indices
  "Produces all the valid indices for a given size."
  [(indices size)])

(documentation: /.zipped
  "Create list zippers with the specified number of input lists."
  [(def: zipped/2 (zipped 2))
   (def: zipped/3 (zipped 3))
   (zipped/3 xs ys zs)
   ((zipped 3) xs ys zs)])

(documentation: /.zipped_with
  "Create list zippers with the specified number of input lists."
  [(def: zipped_with/2 (zipped_with 2))
   (def: zipped_with/3 (zipped_with 3))
   (zipped_with/2 + xs ys)
   ((zipped_with 2) + xs ys)])

(documentation: /.last
  ""
  [(last xs)])

(documentation: /.inits
  (format "For a list of size N, yields the first N-1 elements."
          \n "Will yield a .#None for empty lists.")
  [(inits xs)])

(documentation: /.together
  "The sequential combination of all the lists.")

(documentation: /.with
  "Enhances a monad with List functionality."
  [(with monad)])

(documentation: /.lifted
  "Wraps a monadic value with List machinery."
  [(lifted monad)])

(documentation: /.enumeration
  "Pairs every element in the list with its index, starting at 0."
  [(enumeration xs)])

(documentation: /.when
  "Can be used as a guard in (co)monadic be/do expressions."
  [(do monad
     [value (do_something 1 2 3)
      .when (passes_test? value)]
     (do_something_else 4 5 6))])

(.def: .public documentation
  (.List $.Module)
  ($.module /._
            ""
            [..mixes
             ..reversed
             ..only
             ..partition
             ..pairs

             ..split_at
             ..split_when
             ..sub
             ..repeated
             ..iterations
             ..one
             ..all
             ..example
             ..interposed
             ..size
             
             ..item
             ..sorted
             ..empty?
             ..member?

             ..head
             ..tail
             
             ..indices
             ..zipped
             ..zipped_with
             ..last
             ..inits
             ..together
             ..with
             ..lifted
             ..enumeration
             ..when
             ($.default /.mix)
             ($.default /.equivalence)
             ($.default /.hash)
             ($.default /.monoid)
             ($.default /.functor)
             ($.default /.apply)
             ($.default /.monad)
             ($.default /.zipped/2)
             ($.default /.zipped/3)
             ($.default /.zipped_with/2)
             ($.default /.zipped_with/3)
             ($.default /.first)
             ($.default /.after)
             ($.default /.while)
             ($.default /.until)
             ($.default /.every?)
             ($.default /.any?)]
            []))
