All Downloads are FREE. Search and download functionalities are using the official Maven repository.

typequux.Bool.scala Maven / Gradle / Ivy

/**
  * Copyright 2019 Harshad Deo
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
package typequux

import language.higherKinds

/** Church encodings of booleans.
  *
  * Can be understood as an alias for a type constructor that chooses between one of two alternative types. Is primarily
  * used to enforce the invariants of more complex type-level operations
  *
  * @author Harshad Deo
  * @since 0.1
  */
sealed trait Bool {

  /** Type constructor implementing the choice
    *
    * @author Harshad Deo
    * @since 0.1
    */
  type If[T <: Up, F <: Up, Up] <: Up
}

/** Contains implementation for [[Bool]] and typeconstructor aliases that make usage more pleasant
  *
  * The operations can be shown to satisfy:
  *
  * 1. Associativity of Or:  ||[A, B || C] =:= ||[A || B, C] 
  *
  * 2. Associativity of And:  &&[A, B && C] =:= &&[A && B, C] 
  *
  * 3. Commutativity of Or:  ||[A, B] =:= ||[B, A] 
  *
  * 4. Commutativity of And:  &&[A, B] =:= &&[B, A] 
  *
  * 5. Distributivity of Or over And:  ||[A, B && C] =:= &&[A || B, A || C] 
  *
  * 6. Distributivity of And over Or:  &&[A, B || C] =:= ||[A && B, A && C] 
  *
  * 7. Identity for Or:  ||[A, False] =:= A 
  *
  * 8. Identity for And:  &&[A, True] =:= A 
  *
  * 9. Annhilator for Or:  ||[A, True] =:= True 
  *
  * 10. Annhilator for And:  &&[A, False] =:= False 
  *
  * 11. Idempotence of Or:  ||[A, A] =:= A 
  *
  * 12. Idempotence of And:  &&[A, A] =:= A 
  *
  * 13. Absorption 1:  &&[A, A || B] =:= A 
  *
  * 14. Absorbtion 2:  ||[A, A && B] =:= A 
  *
  * 15. Complementation 1:  &&[A, Not[A]] =:= False 
  *
  * 16. Complementation 2:  ||[A, Not[A]] =:= True 
  *
  * 17. Double Negation:  Not[Not[A]] =:= A 
  *
  * 18. De Morgan 1:  &&[Not[A], Not[B]] =:= Not[A || B] 
  *
  * 19. De Morgan 2:  ||[Not[A], Not[B]] =:= Not[A && B] 
  *
  * @author Harshad Deo
  * @since 0.1
  */
object Bool {

  /** Type constructor for logical conjunction
    *
    *  A && B =:= True if A =:= True and B =:= True 
    *
    *  A && B =:= False otherwise 
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  type &&[A <: Bool, B <: Bool] = A#If[B, False, Bool]

  /** Type constructor for logical disjunction
    *
    *  A || B =:= False if A =:= False and B =:= False 
    *
    *  A || B =:= True otherwise 
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  type ||[A <: Bool, B <: Bool] = A#If[True, B, Bool]

  /** Type constructor for logical negation
    *
    *  Not[True] =:= False 
    *
    *  Not[False] =:= True 
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  type Not[A <: Bool] = A#If[False, True, Bool]

  /** Type constructor for logical exclusive or
    *
    *  A Xor B =:= True  if exactly one of  A =:= True or B =:= True 
    *
    *  A Xor B =:= False  otherwise
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  type Xor[A <: Bool, B <: Bool] = A#If[Not[B], B, Bool]

  /** Typeconstructor for material implication
    *
    *  If A =:= True, A ->> B =:= B 
    *
    *  If A =:= False,  the value of B is ignored and the constructor returns True
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  type ->>[A <: Bool, B <: Bool] = A#If[B, True, Bool]

  /**
    * Type constructor for logical equivalence
    *
    *  A Eqv B =:= True if A =:= B 
    *
    *  A Eqv B =:= False  otherwise
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  type Eqv[A <: Bool, B <: Bool] = A#If[B, Not[B], Bool]

  /** Typelevel representation of a predicate being true
    *
    * @group Implementations
    * @author Harshad Deo
    * @since 0.1
    */
  final class True extends Bool {
    override type If[T <: Up, F <: Up, Up] = T
  }

  /** Typelevel representation of a predicate being False
    *
    * @group Implementations
    * @author Harshad Deo
    * @since 0.1
    */
  final class False extends Bool {
    override type If[T <: Up, F <: Up, Up] = F
  }

  /**
    * Provides a value for a type level boolean
    *
    * @group Implementations
    * @author Harshad Deo
    * @since 0.1
    */
  final class BoolRep[B <: Bool] private (val v: Boolean) extends AnyVal

  /** Provides implicits for converting typelevel booleans to value level booleans
    *
    * @group Implementations
    * @author Harshad Deo
    * @since 0.1
    */
  object BoolRep {

    /** Implements [[BoolRep]] in case of [[True]]
      *
      * @author Harshad Deo
      * @since 0.6.4
      */
    implicit val trueBoolRep: BoolRep[True] = new BoolRep(true)

    /** Implements [[BoolRep]] in case of [[False]]
      *
      * @author Harshad Deo
      * @since 0.6.4
      */
    implicit val falseBoolRep: BoolRep[False] = new BoolRep(false)

  }

  /** Method to convert a typelevel boolean to its value representation
    *
    * @tparam B Type of the boolean to be converted to a value
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  def toBoolean[B <: Bool](implicit ev: BoolRep[B]): Boolean = ev.v
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy