Getting Shapeless With Scala
Getting Shapeless With Scala
Want to learn more about flexible Scala code? Check out this post to learn more about using the shapeless library in Scala.
Join the DZone community and get the full member experience.Join For Free
As time passes by, everyone needs to be fit. This is not always applicable in the field of information technology. In any programming language, it does not matter how much coding experience we have, but there is a period in life when we wonder "if a function or variable could return any of the given datatypes or possible set of values."
Scala provides a better way to represent these needs with its shapeless features. Shapeless Scala allows the code to be fit during particular requirements.
What Is Shapeless?
Shapeless is a library provided by Scala that can be used with a build tool like SBT. One needs to add the following line in the build.sbt file:
libraryDependencies ++= Seq( "com.chuusai" %% "shapeless" % "2.3.3")
Polymorphic functions in Scala are the way to return one type to another type of values without taking any specific type cases of values.
In the above example, we have described a polymorphic value as Seq ~> Option which tells that it takes a sequence of values and returns its head as an option.
If we call the object followed up with a sequence of values, then, we will get the head option of the sequence shown below:
scala> choose(Seq(1,2,3)) res0: Option[Int] = Some(1) scala> choose(Seq()) res1: Option[Nothing] = None
Heterogenous lists are defined as a collection having values of different types. In Scala, shapeless polymorphism provides this as below,
scala> val person: String :: Int :: Boolean :: HNil = "Harsh Sharma" :: 27 :: true :: HNil person: String :: Int :: Boolean :: shapeless.HNil = Harsh Sharma :: 27 :: true :: HNil
As we can see, we have created an employee as a heterogenous list consisting of different information, such as name and age, with the IsEducated followed by the last element as HNil to show the end of a list.
Shapeless provides the
zipper syntax so that one can easily traverse the list and update at a particular place. Consider the following example:
scala> import syntax.zipper._ import syntax.zipper._ scala> val l = 1 :: "foo" :: 3.0 :: HNil l: Int :: String :: Double :: shapeless.HNil = 1 :: foo :: 3.0 :: HNil
Now, we need to find a place that we can insert an element:
scala> l.toZipper.right res5: shapeless.Zipper[Int :: String :: Double :: shapeless.HNil,Int :: shapeless.HNil,String :: Double :: shapeless.HNil,None.type] = Zipper(1 :: HNil,foo :: 3.0 :: HNil,None)
As we can see, HNil represents an empty place on the list and is created just after one place on the right side of the list. First, it points to the right element from the starting of the list.
Finally, we insert an element as:
scala> l.toZipper.right.put("Harsh").reify res6: Int :: String :: Double :: shapeless.HNil = 1 :: Harsh :: 3.0 :: HNil
There you have it! The list traverses in shapeless, as demonstrates above, and we insert the element at the specified position.
Opinions expressed by DZone contributors are their own.