# # Module logic
#
# Operators for first-order/predicate logic
#
#
# :licence: MIT
#   Copyright (c) 2013 Quildreen "Sorella" Motta <quildreen@gmail.com>
#   
#   Permission is hereby granted, free of charge, to any person
#   obtaining a copy of this software and associated documentation files
#   (the "Software"), to deal in the Software without restriction,
#   including without limitation the rights to use, copy, modify, merge,
#   publish, distribute, sublicense, and/or sell copies of the Software,
#   and to permit persons to whom the Software is furnished to do so,
#   subject to the following conditions:
#   
#   The above copyright notice and this permission notice shall be
#   included in all copies or substantial portions of the Software.
#   
#   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
#   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
#   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
#   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
#   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#   SOFTWARE.



# -- Core implementation -----------------------------------------------

# ### Function or
#
# Returns the value of the first truthy function.
#
# :: (A... -> B)... -> A... -> maybe B
Or = ->
  fs = arguments

  -> do
     for f in fs => do
                    result = f.apply this, arguments

                    if result => return result
     return result


# ### Function and
#
# Returns the value of the last truthy function.
#
# :: (A... -> B)... -> A... -> maybe B
And = ->
  fs = arguments

  -> do
     for f in fs => do
                    result = f.apply this, arguments

                    unless result => return result
     return result


# ### Function not
#
# Negates the return value of a function.
#
# :: (A... -> bool) -> A... -> bool
Not = (f) -> -> not (f.apply this, arguments)



# -- Exports -----------------------------------------------------------
module.exports =
  or   : Or
  _or  : Or
  and  : And
  _and : And
  not  : Not
  _not : Not
