Skip to content

Instantly share code, notes, and snippets.

@ubourdon
Created March 22, 2018 16:27
Show Gist options
  • Select an option

  • Save ubourdon/51c7018f092020ef9a3e5bedf2e37448 to your computer and use it in GitHub Desktop.

Select an option

Save ubourdon/51c7018f092020ef9a3e5bedf2e37448 to your computer and use it in GitHub Desktop.
Define non empty list with max size. newtype with smart constructor. Try to set the max size value at compile time
package domain.common.collection
import domain.common.number.strictpositiveint.StrictPositiveInt
import scalaz.Scalaz.ToEitherOps
import scalaz.{@@, NonEmptyList, Tag, \/}
object NonEmptyListMaxSize {
private[NonEmptyListMaxSize] sealed trait NonEmptyListMaxSize2Tag
type NonEmptyListMaxSize2[A] = NonEmptyList[A] @@ NonEmptyListMaxSize2Tag
sealed trait NonEmptyListMaxSizeError
case class NonEmptyListMaxSizeExceeded(maxSize: StrictPositiveInt, size: Int) extends NonEmptyListMaxSizeError
object NonEmptyListMaxSize2 {
def apply[A](rawValue: NonEmptyList[A]): NonEmptyListMaxSizeError \/ NonEmptyListMaxSize2[A] = {
if(rawValue.size <= 2) buildType(rawValue).right
else NonEmptyListMaxSizeExceeded(StrictPositiveInt.TWO, rawValue.size).left
}
/**
* a.k.a unwrap function
* @param nel
* @return the unwrapped NonEmptyList value
*/
def rawValue[A](nel: NonEmptyListMaxSize2[A]): NonEmptyList[A] = Tag.unwrap(nel)
/**
* Allow to use scalaz Show typeclass
*/
//implicit val showNonEmptyListMaxSize2[A]: Show[NonEmptyListMaxSize2[A]] = Show shows { i => s"NonEmptyListMaxSize2(${Tag.unwrap(i)})"}
private def buildType[A](nel: NonEmptyList[A]) = Tag.apply[NonEmptyList[A], NonEmptyListMaxSize2Tag](nel)
implicit class NonEmptyListMaxSize2Ops[A](nel_2: NonEmptyListMaxSize2[A]) {
def list: List[A] = rawValue(nel_2).list
def head: A = rawValue(nel_2).head
def tail: List[A] = rawValue(nel_2).tail
def +(x: A): NonEmptyListMaxSizeError \/ NonEmptyListMaxSize2[A] = apply(rawValue(nel_2).:::>(x :: Nil))
}
}
}
@ubourdon
Copy link
Author

En fait je voudrais pouvoir "variabiliser" rawValue.size <= 2 dans la méthode apply mais au compile time.

Pour pouvoir définir le MaxSize dans la signature du type et définir par exemple :

case class Toto(maliste: NonEmptyListmaxSize[MaxSize_5, String])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment