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

typequux.DenseMap.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 Bool.{False, True}
import Dense._
import DenseSet.EmptyDenseSet
import language.higherKinds

/** Typelevel map in which the keys are [[Dense]] numbers. Implemented a binary tree.
  *
  * @author Harshad Deo
  * @since 0.1
  */
sealed trait DenseMap {

  /** Check if the key is present in the map
    *
    * @author Harshad Deo
    * @since 0.1
    */
  type Contains[K <: Dense] <: Bool

  /** Add a key and a value to the map. If the key is already present, the value is overridden
    *
    * @author Harshad Deo
    * @since 0.1
    */
  type Add[K <: Dense, V] <: DenseMap

  /** Remove a key from the map
    *
    * @author Harshad Deo
    * @since 0.1
    */
  type Remove[K <: Dense] <: DenseMap

  /** Get the value corresponding to the key
    *
    * @author Harshad Deo
    * @since 0.1
    */
  type Get[K <: Dense]

  /** Union of the two dense maps. If two values share the same key, the value in the resultant map cannot be
    * predicted.
    *
    * @author Harshad Deo
    * @since 0.1
    */
  type Union[X <: DenseMap] <: DenseMap

  /** The set of keys present in the map
    *
    * @author Harshad Deo
    * @since 0.1
    */
  type Keyset <: DenseSet

  /** Typelevel size of the Map
    *
    * @author Harshad Deo
    * @since 0.1
    */
  type Size <: Dense

  type FoldL[Init <: Type, Type, F <: Fold2[Dense, Any, Type]] <: Type
}

/** Contains implementation traits for [[DenseMap]] and typeconstructor aliases that make usage more pleasant.
  *
  * @author Harshad Deo
  * @since 0.1
  */
object DenseMap {

  /** Empty Map, base case for constructing all maps
    *
    * @group Implementation
    * @author Harshad Deo
    * @since 0.1
    */
  trait EmptyDenseMap extends DenseMap {
    override type Contains[K <: Dense] = False
    override type Add[K <: Dense, V] = NonEmptyDenseMap[K, V, EmptyDenseMap, EmptyDenseMap]
    override type Remove[K <: Dense] = EmptyDenseMap
    override type Get[K <: Dense] = Nothing
    override type Union[X <: DenseMap] = X
    override type Keyset = EmptyDenseSet
    override type Size = Dense._0
    override type FoldL[Init <: Type, Type, F <: Fold2[Dense, Any, Type]] = Init
  }

  /** Non empty typelevel map, implemented as a binary tree.
    *
    * @tparam KT Type of the key
    * @tparam VT Value associated with KT
    * @tparam L DenseMap in which all keys are less than KT
    * @tparam R DenseMap in which all keys are greater than KT
    *
    * @group Implementation
    * @author Harshad Deo
    * @since 0.1
    */
  trait NonEmptyDenseMap[KT <: Dense, VT, L <: DenseMap, R <: DenseMap] extends DenseMap {
    override type Contains[K <: Dense] = K#Compare[KT]#Match[L#Contains[K], True, R#Contains[K], Bool]
    override type Add[K <: Dense, V] = K#Compare[KT]#Match[NonEmptyDenseMap[KT, VT, L#Add[K, V], R],
                                                           NonEmptyDenseMap[KT, V, L, R],
                                                           NonEmptyDenseMap[KT, VT, L, R#Add[K, V]],
                                                           DenseMap]
    override type Remove[K <: Dense] = K#Compare[KT]#Match[NonEmptyDenseMap[KT, VT, L#Remove[K], R],
                                                           L#Union[R],
                                                           NonEmptyDenseMap[KT, VT, L, R#Remove[K]],
                                                           DenseMap]
    override type Get[K <: Dense] = K#Compare[KT]#Match[L#Get[K], VT, R#Get[K], Any]
    override type Union[X <: DenseMap] = FoldL[X, DenseMap, UnionFold]
    override type Keyset = DenseSet.NonEmptyDenseSet[KT, L#Keyset, R#Keyset]
    override type Size = _1 + L#Size + R#Size
    type FoldL[Init <: Type, Type, F <: Fold2[Dense, Any, Type]] =
      R#FoldL[F#Apply[KT, VT, L#FoldL[Init, Type, F]], Type, F]
  }

  trait UnionFold extends Fold2[Dense, Any, DenseMap] {
    override type Apply[K <: Dense, V, Acc <: DenseMap] = Acc#Add[K, V]
  }

  /** Alias to check if a key is present in the map
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  type Contains[M <: DenseMap, K <: Dense] = M#Contains[K]

  /** Alias to remove a key (and its corresponding value) from the map
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  type Remove[M <: DenseMap, K <: Dense] = M#Remove[K]

  /** Alias to get the value associated with a key
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  type Get[M <: DenseMap, K <: Dense] = M#Get[K]

  /** Alias to get the union of two dense maps
    *
    * @group Operations
    * @author Harshad Deo
    * @since 0.1
    */
  type Union[M <: DenseMap, N <: DenseMap] = M#Union[N]
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy