How to check formlessness if a type is a member of an HList?

I am doing a sequence of steps to preprocess strings, and I was thinking of using HListmy steps to increase the security. Some processing steps should be performed after others, so I was thinking about coding in the type system. My first attempt:

trait Step
trait Raw extends Step
trait A extends Step
trait B extends Step
trait DependsOnA extends Step
trait DependsOnB extends Step

case class ToBeProcessed[S <: Step](value: String)

object ToBeProcessed {
    def raw(input: String): ToBeProcessed[Raw] = ...
    def doA(input: ToBeProcessed[Raw]): ToBeProcessed[A] = ...
    def doB(input: ToBeProcessed[A]): ToBeProcessed[B] = ...
    def doDependsOnA(input: ToBeProcessed[B]): ToBeProcessed[DependsOnA] = ...
    def doDependsOnB(input: ToBeProcessed[DependsOnA]): ToBeProcessed[DependsOnB] = ...
}

It works because it forces me to call all in a sequence of doA> doB> doDependsOnA> doDependsOnBthat it is possible to order her work, but:

  • it makes you depend on steps that are independent of each other.
  • If I want to implement a new intermediate step doC, I have to change the types of things that are not related to it.

, Haskell , . Shapeless HList, :

case class ToBeProcessed[S <: HList](value: String)

object ToBeProcessed {
    def raw(input: String): ToBeProcessed[Raw :: HNil] = ...
    def doA[S <: HList](input: ToBeProcessed[S]): ToBeProcessed[A :: S] = ...
    def doB[S <: HList](input: ToBeProcessed[S]): ToBeProcessed[B :: S] = ...

, A HList:

    def doDependsOnA[S <: HList, ???](input: ToBeProcessed[S]): ToBeProcessed[DependsOnA :: S] = ...

}

??? - , S A. , . ?

+4
1

Shapeless , a HList : Selector. :

import shapeless._, ops.hlist.Selector

def doDependsOnA[S <: HList](input: ToBeProcessed[S])(implicit ev: Selector[S,A]): ToBeProcessed[DependsOnA :: S] = ???
+3

Source: https://habr.com/ru/post/1669418/


All Articles