(.require
 [library
  [lux (.except)
   ["$" documentation]
   [data
    ["[0]" text (.only \n)
     ["%" \\format (.only format)]]]]]
 [\\library
  ["[0]" /]])

(def .public documentation
  (List $.Documentation)
  (list ($.module /._
                  "")

        ($.definition /.a/an
          (format "Automatic implementation selection (for type-class style polymorphism)."
                  \n "This feature layers type-class style polymorphism on top of Lux's signatures and implementations."
                  \n "When calling a polymorphic function, or using a polymorphic constant,"
                  \n "this macro will check the types of the arguments, and the expected type for the whole expression"
                  \n "and it will search in the local scope, the module's scope and the imports' scope"
                  \n "in order to find suitable implementations to satisfy those requirements."
                  \n "If a single alternative is found, that one will be used automatically."
                  \n "If no alternative is found, or if more than one alternative is found (ambiguity)"
                  \n "a compile-time error will be raised, to alert the user."
                  \n \n "Caveat emptor: You need to make sure to import the module of any implementation you want to use."
                  \n "Otherwise, this macro will not find it.")
          ["Nat equivalence"
           (at number.equivalence = x y)
           (a/an = x y)]
          ["Can optionally add the prefix of the module where the signature was defined."
           (a/an equivalence.= x y)]
          ["(List Nat) equivalence"
           (a/an =
                 (list.indices 10)
                 (list.indices 10))]
          ["(Functor List) each"
           (a/an each ++ (list.indices 10))])

        ($.definition /.with
          "Establish lexical bindings for implementations that will be prioritized over non-lexically-bound implementations."
          [(with [n.addition]
             (n.= (at n.addition composite left right)
                  (a/an composite left right)))])

        ($.definition /.implicitly
          "Establish local definitions for implementations that will be prioritized over foreign definitions."
          [(implicitly n.multiplication)
           
           (n.= (at n.multiplication composite left right)
                (a/an composite left right))])
        ))
