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

org.kynthus.hatalib.argparse.instance.InitialInstances0.scala Maven / Gradle / Ivy

The newest version!
package org.kynthus.hatalib.argparse.instance

import org.kynthus.hatalib.argparse.concept.Initial
import org.kynthus.hatalib.argparse.syntax.InitialSyntax.InitialOps
import org.kynthus.hatalib.core.concept.{Field, ResultCategory, Run}
import org.kynthus.hatalib.core.syntax.FieldSyntax.FieldOps
import org.kynthus.hatalib.core.syntax.TagSyntax.TagOps
import scalaz.Leibniz.===
import scalaz.syntax.applicative.ApplicativeIdV
import scalaz.syntax.bind.ToBindOps
import scalaz.syntax.tag.ToTagOps
import scalaz.{@@, Applicative, Bind}
import scopt.OParser
import shapeless.labelled.FieldType
import shapeless.ops.record.{Merger, Remover, Selector, Updater}
import shapeless.record.recordOps
import shapeless.{HList, HNil, Refute}

import scala.collection.immutable.Queue
import scala.language.higherKinds

/**
 * 初期値を持つフィールドを追加するための型クラスインスタンスの第1候補です。
 *
 * @author Kynthus Auoeau
 * @since 1.0.0
 * @version 1.0.0
 */
private[instance] trait InitialInstances0 extends Any {

  /**
   * 構築中の情報へ初期値を付与します。
   *
   * @param runCategory     動作設定を持つ値を格納する型を決定するマーカー
   * @param applicative     構築中の情報をラップ可能なことを保証する
   * @param initialField    初期値として付与する型がフィールドへ変換可能なことを保証する
   * @param decidedUpdater  構築中の情報の決定済みパーサを更新できることを保証する
   * @param initialUpdater  構築中の情報へ初期値を付与できることを保証する
   * @param currentNotExist 構築中の情報が現在設定中のパーサを持たないことを保証する
   * @param initialNotExist 構築中の情報がまだ初期値を持たないことを保証する
   * @tparam ConvertingField  フィールドへ変換する型
   * @tparam ConvertedField   フィールドへ変換した型
   * @tparam UnusedKeys       パーサへのオプション追加時に使用する幽霊型(動作設定時は未使用)
   * @tparam InsertingInitial 初期値の付与対象となる型
   * @tparam InsertedDecided  決定済みパーサを更新した後の型
   * @tparam InsertedInitial  初期値を付与した後の型
   * @tparam InsertedCategory 構築中の情報をラップする型
   * @return 構築中の情報へ初期値を付与する型クラスインスタンス
   * @author Kynthus Auoeau
   * @since 1.0.0
   * @version 1.0.0
   */
  implicit final def InsertInitial[
    ConvertingField,
    ConvertedField <: HList,
    UnusedKeys,
    InsertingInitial <: HList,
    InsertedDecided <: HList,
    InsertedInitial <: HList,
    InsertedCategory[_]
  ](
     implicit
     runCategory: ResultCategory[InsertedCategory] @@ Run.type,
     applicative: Applicative[InsertedCategory],
     initialField: Field.Aux[
       ConvertingField,
       ConvertedField
     ],
     decidedUpdater: Updater.Aux[
       InsertingInitial,
       FieldType[
         ParserDecided.T,
         List[Queue[OParser[_, ConvertedField]]]
       ],
       InsertedDecided
     ],
     initialUpdater: Updater.Aux[
       InsertedDecided,
       FieldType[
         InitialRecord.T,
         ConvertedField
       ],
       InsertedInitial
     ],
     currentNotExist: Refute[
       Selector[
         InsertingInitial,
         ParserCurrent.T
       ]
     ],
     initialNotExist: Refute[
       Selector[
         InsertingInitial,
         InitialRecord.T
       ]
     ]
   ): Initial.Aux[
    InsertingInitial @@ UnusedKeys,
    ConvertingField,
    InsertedCategory[InsertedInitial @@ (Unit @@ ConvertedField)]
  ] = InitialInstances0.InsertInitial

  /**
   * 構築中の情報へ初期値を追加します。
   *
   * @param runCategory       動作設定を持つ値を格納する型を決定するマーカー
   * @param applicative       構築中の情報をラップ可能なことを保証する
   * @param initialField      初期値として付与する型がフィールドへ変換可能なことを保証する
   * @param initialSelector   構築中の情報から設定済みの初期値を取得できることを保証する
   * @param initialRemover    構築中の情報から設定済みの初期値を削除できることを保証する
   * @param initialMerger     設定済みの初期値と新しい初期値がマージ可能なことを保証する
   * @param decidedRemover    構築中の情報から決定済みのパーサを削除できることを保証する
   * @param decidedUpdater    構築中の情報へ新しい決定済みのパーサを追加しなおせることを保証する
   * @param initialUpdater    構築中の情報へ新しい初期値を設定しなおせることを保証する
   * @param currentNotExist   構築中の情報に現在設定中のパーサが存在しないことを保証する
   * @param hierarchySelector 構築中の情報がパーサ階層を持つことを保証する
   * @param hierarchyIsEmpty  構築中の情報が保持するパーサ階層が空の状態であることを保証する
   * @tparam ConvertingField フィールドへ変換する型
   * @tparam ConvertedField  フィールドへ変換した型
   * @tparam Input           パーサの現在値の型
   * @tparam UpdatingInitial 初期値の追加対象となる型
   * @tparam ExistInitial    現在の初期値の型
   * @tparam RemovedInitial  構築中の情報から設定済みの初期値を削除した後の型
   * @tparam ExistDecided    現在の決定済みパーサの型
   * @tparam RemovedDecided  構築中の情報から決定済みパーサを削除した後の型
   * @tparam MergedInitial   現在の初期値と追加する初期値をマージした型
   * @tparam ExistHierarchy  現在のパーサ階層の型
   * @tparam UpdatedDecided  構築中の情報へ新しい決定済みパーサを追加しなおした型
   * @tparam UpdatedInitial  構築中の情報へ新しい初期値を設定しなおした型
   * @tparam UpdatedCategory 構築中の情報をラップする型
   * @return 構築中の情報へ初期値を追加する型クラスインスタンス
   * @author Kynthus Auoeau
   * @since 1.0.0
   * @version 1.0.0
   */
  implicit final def UpdateInitial[
    ConvertingField,
    ConvertedField <: HList,
    Input,
    UpdatingInitial <: HList,
    ExistInitial <: HList,
    RemovedInitial <: HList,
    ExistDecided,
    RemovedDecided <: HList,
    MergedInitial <: HList,
    ExistHierarchy <: HList,
    UpdatedDecided <: HList,
    UpdatedInitial <: HList,
    UpdatedCategory[_]
  ](
     implicit
     runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
     applicative: Applicative[UpdatedCategory],
     initialField: Field.Aux[
       ConvertingField,
       ConvertedField
     ],
     initialSelector: Selector.Aux[
       UpdatingInitial,
       InitialRecord.T,
       ExistInitial
     ],
     initialRemover: Remover.Aux[
       UpdatingInitial,
       InitialRecord.T,
       (ExistInitial, RemovedInitial)
     ],
     initialMerger: Merger.Aux[
       ExistInitial,
       ConvertedField,
       MergedInitial
     ],
     decidedRemover: Remover.Aux[
       RemovedInitial,
       ParserDecided.T,
       (ExistDecided, RemovedDecided)
     ],
     decidedUpdater: Updater.Aux[
       RemovedDecided,
       FieldType[
         ParserDecided.T,
         List[Queue[OParser[_, MergedInitial]]]
       ],
       UpdatedDecided
     ],
     initialUpdater: Updater.Aux[
       UpdatedDecided,
       FieldType[
         InitialRecord.T,
         MergedInitial
       ],
       UpdatedInitial
     ],
     currentNotExist: Refute[
       Selector[
         UpdatingInitial,
         ParserCurrent.T
       ]
     ],
     hierarchySelector: Selector.Aux[
       UpdatingInitial,
       ParserHierarchy.T,
       ExistHierarchy
     ],
     hierarchyIsEmpty: ExistHierarchy === HNil
   ): Initial.Aux[
    UpdatingInitial @@ (Input @@ ExistInitial),
    ConvertingField,
    UpdatedCategory[UpdatedInitial @@ (Input @@ MergedInitial)]
  ] = InitialInstances0.UpdateInitial

  /**
   * ラップされた型に対して初期値設定を行います。
   *
   * @param runCategory 初期値を持つ値を格納する型を決定するマーカー
   * @param bind        平坦化変換が可能なことを保証する
   * @param base        ラップされた型に対して初期値設定が行えることを保証する
   * @tparam ConvertingField フィールドへ変換する値
   * @tparam ConvertedField  フィールドへ変換した値
   * @tparam DerivedInitial  初期値設定前の型
   * @tparam OutputInitial   初期値設定後の型
   * @tparam OutputCategory  構築中の情報をラップする型
   * @return ラップされた型に対して初期値設定を行う型クラスインスタンス
   * @author Kynthus Auoeau
   * @since 1.0.0
   * @version 1.0.0
   */
  implicit final def CategoryInitial[
    ConvertingField,
    ConvertedField <: HList,
    DerivedInitial,
    OutputInitial,
    OutputCategory[_]
  ](
     implicit
     runCategory: ResultCategory[OutputCategory] @@ Run.type,
     bind: Bind[OutputCategory],
     base: Initial.Aux[
       DerivedInitial,
       ConvertingField,
       OutputCategory[OutputInitial]
     ]
   ): Initial.Aux[
    OutputCategory[DerivedInitial],
    ConvertingField,
    OutputCategory[OutputInitial]
  ] = InitialInstances0.CategoryInitial

}

/**
 * 初期値を持つフィールドを追加するための型クラスインスタンスの第1候補を内部的に定義します。
 *
 * @author Kynthus Auoeau
 * @since 1.0.0
 * @version 1.0.0
 */
private object InitialInstances0 extends AnyRef {

  /**
   * 構築中の情報へ初期値を付与します(内部)。
   *
   * @param runCategory     動作設定を持つ値を格納する型を決定するマーカー
   * @param applicative     構築中の情報をラップ可能なことを保証する
   * @param initialField    初期値として付与する型がフィールドへ変換可能なことを保証する
   * @param decidedUpdater  構築中の情報の決定済みパーサを更新できることを保証する
   * @param initialUpdater  構築中の情報へ初期値を付与できることを保証する
   * @param currentNotExist 構築中の情報が現在設定中のパーサを持たないことを保証する
   * @param initialNotExist 構築中の情報がまだ初期値を持たないことを保証する
   * @tparam ConvertingField  フィールドへ変換する型
   * @tparam ConvertedField   フィールドへ変換した型
   * @tparam UnusedKeys       パーサへのオプション追加時に使用する幽霊型(動作設定時は未使用)
   * @tparam InsertingInitial 初期値の付与対象となる型
   * @tparam InsertedDecided  決定済みパーサを更新した後の型
   * @tparam InsertedInitial  初期値を付与した後の型
   * @tparam InsertedCategory 構築中の情報をラップする型
   * @return 構築中の情報へ初期値を付与する型クラスインスタンス
   * @author Kynthus Auoeau
   * @since 1.0.0
   * @version 1.0.0
   */
  private final def InsertInitial[
    ConvertingField,
    ConvertedField <: HList,
    UnusedKeys,
    InsertingInitial <: HList,
    InsertedDecided <: HList,
    InsertedInitial <: HList,
    InsertedCategory[_]
  ](
     implicit
     runCategory: ResultCategory[InsertedCategory] @@ Run.type,
     applicative: Applicative[InsertedCategory],
     initialField: Field.Aux[
       ConvertingField,
       ConvertedField
     ],
     decidedUpdater: Updater.Aux[
       InsertingInitial,
       FieldType[
         ParserDecided.T,
         List[Queue[OParser[_, ConvertedField]]]
       ],
       InsertedDecided
     ],
     initialUpdater: Updater.Aux[
       InsertedDecided,
       FieldType[
         InitialRecord.T,
         ConvertedField
       ],
       InsertedInitial
     ],
     currentNotExist: Refute[
       Selector[
         InsertingInitial,
         ParserCurrent.T
       ]
     ],
     initialNotExist: Refute[
       Selector[
         InsertingInitial,
         InitialRecord.T
       ]
     ]
   ): Initial.Aux[
    InsertingInitial @@ UnusedKeys,
    ConvertingField,
    InsertedCategory[InsertedInitial @@ (Unit @@ ConvertedField)]
  ] = new Initial[InsertingInitial @@ UnusedKeys] {

    /**
     * 最初の初期値として設定可能なフィールドです。
     *
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    override type Member = ConvertingField

    /**
     * 最初の初期値の追加後に返すべき型です。
     *
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    override type Result = InsertedCategory[InsertedInitial @@ (Unit @@ ConvertedField)]

    /**
     * 初期値を付与した結果を返します。
     *
     * @param derived まだ初期値を持たない値
     * @param member  付与する初期値
     * @return 構築中の情報へ初期値を付与した結果
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    override def apply
    (
      derived: => InsertingInitial @@ UnusedKeys,
      member: => super.Member
    ): super.Result = this (derived) = member.field

    /**
     * 構築中の情報へ初期値を付与します。
     *
     * @param derived まだ初期値を持たない値
     * @param field   付与する初期値
     * @return 構築中の情報へ初期値を付与した結果
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    private[this] def update
    (
      derived: InsertingInitial @@ UnusedKeys,
      field: ConvertedField
    ): super.Result = {

      // 空の決定済みパーサを生成して追加
      val defaultParserDecided: List[Queue[OParser[_, ConvertedField]]] = Queue.empty :: Nil
      val insertedDecided: InsertedDecided = derived.unwrap.updated(ParserDecided, defaultParserDecided)

      // 初期値を付与
      val insertedInitial: InsertedInitial = insertedDecided.updated(InitialRecord, field)

      // 再度タグ付けして返す
      val result: InsertedInitial @@ (Unit @@ ConvertedField) = insertedInitial.wrap
      result.pure

    }

  }

  /**
   * 構築中の情報へ初期値を追加します(内部)。
   *
   * @param runCategory       動作設定を持つ値を格納する型を決定するマーカー
   * @param applicative       構築中の情報をラップ可能なことを保証する
   * @param initialField      初期値として付与する型がフィールドへ変換可能なことを保証する
   * @param initialSelector   構築中の情報から設定済みの初期値を取得できることを保証する
   * @param initialRemover    構築中の情報から設定済みの初期値を削除できることを保証する
   * @param initialMerger     設定済みの初期値と新しい初期値がマージ可能なことを保証する
   * @param decidedRemover    構築中の情報から決定済みのパーサを削除できることを保証する
   * @param decidedUpdater    構築中の情報へ新しい決定済みのパーサを追加しなおせることを保証する
   * @param initialUpdater    構築中の情報へ新しい初期値を設定しなおせることを保証する
   * @param currentNotExist   構築中の情報に現在設定中のパーサが存在しないことを保証する
   * @param hierarchySelector 構築中の情報がパーサ階層を持つことを保証する
   * @param hierarchyIsEmpty  構築中の情報が保持するパーサ階層が空の状態であることを保証する
   * @tparam ConvertingField フィールドへ変換する型
   * @tparam ConvertedField  フィールドへ変換した型
   * @tparam Input           パーサの現在値の型
   * @tparam UpdatingInitial 初期値の追加対象となる型
   * @tparam ExistInitial    現在の初期値の型
   * @tparam RemovedInitial  構築中の情報から設定済みの初期値を削除した後の型
   * @tparam ExistDecided    現在の決定済みパーサの型
   * @tparam RemovedDecided  構築中の情報から決定済みパーサを削除した後の型
   * @tparam MergedInitial   現在の初期値と追加する初期値をマージした型
   * @tparam ExistHierarchy  現在のパーサ階層の型
   * @tparam UpdatedDecided  構築中の情報へ新しい決定済みパーサを追加しなおした型
   * @tparam UpdatedInitial  構築中の情報へ新しい初期値を設定しなおした型
   * @tparam UpdatedCategory 構築中の情報をラップする型
   * @return 構築中の情報へ初期値を追加する型クラスインスタンス
   * @author Kynthus Auoeau
   * @since 1.0.0
   * @version 1.0.0
   */
  private final def UpdateInitial[
    ConvertingField,
    ConvertedField <: HList,
    Input,
    UpdatingInitial <: HList,
    ExistInitial <: HList,
    RemovedInitial <: HList,
    ExistDecided,
    RemovedDecided <: HList,
    MergedInitial <: HList,
    ExistHierarchy <: HList,
    UpdatedDecided <: HList,
    UpdatedInitial <: HList,
    UpdatedCategory[_]
  ](
     implicit
     runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
     applicative: Applicative[UpdatedCategory],
     initialField: Field.Aux[
       ConvertingField,
       ConvertedField
     ],
     initialSelector: Selector.Aux[
       UpdatingInitial,
       InitialRecord.T,
       ExistInitial
     ],
     initialRemover: Remover.Aux[
       UpdatingInitial,
       InitialRecord.T,
       (ExistInitial, RemovedInitial)
     ],
     initialMerger: Merger.Aux[
       ExistInitial,
       ConvertedField,
       MergedInitial
     ],
     decidedRemover: Remover.Aux[
       RemovedInitial,
       ParserDecided.T,
       (ExistDecided, RemovedDecided)
     ],
     decidedUpdater: Updater.Aux[
       RemovedDecided,
       FieldType[
         ParserDecided.T,
         List[Queue[OParser[_, MergedInitial]]]
       ],
       UpdatedDecided
     ],
     initialUpdater: Updater.Aux[
       UpdatedDecided,
       FieldType[
         InitialRecord.T,
         MergedInitial
       ],
       UpdatedInitial
     ],
     currentNotExist: Refute[
       Selector[
         UpdatingInitial,
         ParserCurrent.T
       ]
     ],
     hierarchySelector: Selector.Aux[
       UpdatingInitial,
       ParserHierarchy.T,
       ExistHierarchy
     ],
     hierarchyIsEmpty: ExistHierarchy === HNil
   ): Initial.Aux[
    UpdatingInitial @@ (Input @@ ExistInitial),
    ConvertingField,
    UpdatedCategory[UpdatedInitial @@ (Input @@ MergedInitial)]
  ] = new Initial[UpdatingInitial @@ (Input @@ ExistInitial)] {

    /**
     * 初期値として設定可能なフィールドです。
     *
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    override type Member = ConvertingField

    /**
     * 初期値の追加後に返すべき型です。
     *
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    override type Result = UpdatedCategory[UpdatedInitial @@ (Input @@ MergedInitial)]

    /**
     * 構築中の情報が持つ初期値へ追加した結果を返します。
     *
     * @param derived 初期値を持つ値
     * @param member  追加する初期値
     * @return 構築中の情報が持つ初期値へ追加した結果
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    override def apply
    (
      derived: => UpdatingInitial @@ (Input @@ ExistInitial),
      member: => super.Member
    ): super.Result = this (derived) = _.merge(member.field)

    /**
     * 構築中の情報が持つ初期値へ追加した結果を返します。
     *
     * @param derived  初期値を持つ値
     * @param function 初期値を追加する処理
     * @return 構築中の情報が持つ初期値へ追加した結果
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    private[this] def update
    (
      derived: UpdatingInitial @@ (Input @@ ExistInitial),
      function: ExistInitial => MergedInitial
    ): super.Result = {

      // 構築した情報からタグを外す
      val updatingInitial: UpdatingInitial = derived.unwrap

      // 設定済みの初期値を取得し、削除する
      val (existInitial, removedInitial):
        (ExistInitial, RemovedInitial) =
        updatingInitial.remove(InitialRecord)

      // 初期値が変わるため、決定済みパーサを全て破棄する
      val removedDecided: RemovedDecided = removedInitial - ParserDecided

      // 新しい初期値に対応する空の決定済みパーサを設定しなおす
      val defaultParserDecided: List[Queue[OParser[_, MergedInitial]]] = Queue.empty :: Nil
      val decidedInitial: UpdatedDecided =
        removedDecided.updated(ParserDecided, defaultParserDecided)

      // 新しい初期値で更新する
      val updatedInitial: UpdatedInitial =
        decidedInitial.updated(InitialRecord, function(existInitial))

      // 再度タグ付けして返す
      val result: UpdatedInitial @@ (Input @@ MergedInitial) = updatedInitial.wrap
      result.pure

    }

  }

  /**
   * ラップされた型に対して初期値設定を行います(内部)。
   *
   * @param runCategory 初期値を持つ値を格納する型を決定するマーカー
   * @param bind        平坦化変換が可能なことを保証する
   * @param base        ラップされた型に対して初期値設定が行えることを保証する
   * @tparam ConvertingField フィールドへ変換する値
   * @tparam ConvertedField  フィールドへ変換した値
   * @tparam DerivedInitial  初期値設定前の型
   * @tparam OutputInitial   初期値設定後の型
   * @tparam OutputCategory  構築中の情報をラップする型
   * @return ラップされた型に対して初期値設定を行う型クラスインスタンス
   * @author Kynthus Auoeau
   * @since 1.0.0
   * @version 1.0.0
   */
  private final def CategoryInitial[
    ConvertingField,
    ConvertedField <: HList,
    DerivedInitial,
    OutputInitial,
    OutputCategory[_]
  ](
     implicit
     runCategory: ResultCategory[OutputCategory] @@ Run.type,
     bind: Bind[OutputCategory],
     base: Initial.Aux[
       DerivedInitial,
       ConvertingField,
       OutputCategory[OutputInitial]
     ]
   ): Initial.Aux[
    OutputCategory[DerivedInitial],
    ConvertingField,
    OutputCategory[OutputInitial]
  ] = new Initial[OutputCategory[DerivedInitial]] {

    /**
     * 初期値として設定可能なフィールドです。
     *
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    override type Member = ConvertingField

    /**
     * 初期値の追加後に返すべき型です。
     *
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    override type Result = OutputCategory[OutputInitial]

    /**
     * ラップされた型に対して初期値を追加した結果を返します。
     *
     * @param derived 初期値を持つ値
     * @param member  追加する初期値
     * @return 初期値を追加した結果
     * @author Kynthus Auoeau
     * @since 1.0.0
     * @version 1.0.0
     */
    override def apply
    (
      derived: => OutputCategory[DerivedInitial],
      member: => super.Member
    ): super.Result = derived >>= (_.initial(member))

  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy