Fuzion Logo
flang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

monad.fz


# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation.  If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
#  Tokiwa Software GmbH, Germany
#
#  Source code of Fuzion standard library feature monad
#
#  Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------

# monad -- generic monad
#
# A monad in X is just a monoid in the category of endofunctors of X, with
# product × replaced by composition of endofunctors and unit set by the
# identity endofunctor.
#       -- Saunder Mac Lane, Categories for the Working Mathematician, 1971
#
# Don't be scared, in Java terms: A monad is a means to compose functions
# applied to generic types.
#
#
monad (A type, MA (monad A MA).type) is


  # monadic operator within the same monad
  #
  # Apply f to elements of type A and re-wrap them in this monad.
  #
  infix >>= (f A -> MA) MA is abstract


  # monadic operator to another monad
  #
  # Apply f to elements of type A and wrap them in MB.
  #
  # NYI: This is currently useless since a redefinition is not
  # allowed for features with generic arguments. Is there a way
  # we could allow this anyway?
  #
  infix >>=~ (B, MB type, f A -> MB) MB is abstract


  # join operator
  #
  # NYI: useless since redefinition currently not supported for
  # feature with generics.
  #
  join(MMA (monad MA (monad A MA)).type, a MMA) MA is abstract


  # NYI: fmap:
  #
  # fmap<B> (f A -> B) is monad.this >>= fun (x A) B is return f x


# type related to monad declaring features not requiring an instance of monad
#
monads(A type, MA (monad A MA).type) is


  # return function
  #
  return (a A) MA is abstract