A mini Scala utility library. Compatible with functional programming beginners. For the JVM and Scala.js.
It may help you understand how to use - and how to implement (looking at the code) - some popular functional programming features. Il also provides some useful utilities.
Hamsters "full" lib is compatible with Scala 2.11 and 2.12. Some parts of the lib, that are not relying on Scala Meta macros are compatible with 2.13 and extracted in their own repository.
Currently, Hamsters supports :
-
Data validation
-
Default values for options (orEmpty)
-
Enum typeclass
-
Future Squash (simplifications for nested types)
-
HLists
-
Lens
-
mapN
-
Memoization
-
Monad transformers
-
NonEmptyList
-
Retry
-
Sealed traits children listing
-
Show (better toString)
-
Union types
libraryDependencies ++= Seq(
"io.github.scala-hamsters" %% "hamsters" % "3.1.0"
)
For Scala.js :
libraryDependencies ++= Seq(
"io.github.scala-hamsters" %%% "hamsters" % "3.1.0"
)
See hamsters-extensions for more information.
You can find the API documentation here.
To Laurence Beillaux who created the Hamsters logo.
hamsters's People
Forkers
ikhoon mdulac daewon mikalv fabszn museonsite thomasgrt sohum2002 miguelbasire raulraja remk urcadox sh0hei denisrosca flavioprosperi kurtlogan andys8 porcupine96 oraclewalid ggrossetie notflorian dgouyettehamsters's Issues
HList : Wrong type returned by compiler with ++ function
This is working :
val sum = (2.0 :: "hi" :: HNil) ++ (1 :: HNil)
sum shouldBe 2.0 :: "hi" :: 1 :: HNil
sum shouldBe a[HCons[_, HCons[_, HCons[_, HNil]]]]
Folding/Iterating on sum content works as expected :
sum.foreach(println)
Result :
// 2.0
// hi
// 1
But this fails :
sum.tail.tail.head
--> compilation error : value head is not a member of io.github.hamsters.HNil
We can see with the first test that sum.tail.tail is a HCons but the compiler returns a HNIL because ++ keeps the type of the first HList, HCons[_, HCons[_, HNil]]]
in this example instead of [HCons[_, HCons[_, HCons[_, HNil]]]]
.
Too much transitive dependencies
If i create an empty project and make
sbt clean && sbt clean && sbt assembly && ls -lah target/scala-2.12/*.jar
I get a weight :
libraryDependencies += "io.github.scala-hamsters" %% "hamsters" % "1.5.1"
=> 14Mo
libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.2"
=> 7.7 Mo
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.2.16"
=> 13.1Mo
Our dependencies depends of scala.meta, it should be a provided depency
Implement Show typeclass
The goal is to automatically provide a better toString for case classes with field names.
Example :
case class Person(name: String, age: Int)
implicit personShow = ... // calling macro here
val p = Person("bob", 40)
Show.show(p) // returns "Person(name = bob, age = 40)"
//or
// import implicit class
p.show // returns "Person(name = bob, age = 40)"
Implement non empty list
Generate Validation.result up to 22 parameters
Write scaladoc for all public methods
Implement wait in retry
Add another method like this :
def apply[T](maxRetries: Int, waitInMilliSeconds: Int, errorFn: (String) => Unit = _=> Unit)(fn: => T): Future[T]
Future will be used to avoid blocking in the main thread
Enumerable.parse should compare string in the same case
trait Enumerable[A] {
def name(a: A): String = a.toString.toLowerCase
def parse(s: String): Option[A] = list.find(a => name(a) == s)
def list: List[A]
}
should become
trait Enumerable[A] {
def name(a: A): String = a.toString.toLowerCase
def parse(s: String): Option[A] = list.find(a => name(a).equalsIgnoreCase(s))
def list: List[A]
}
Move documentation in a separated directory
We should keep a link to the doc in the Readme
cross build is broken
sbt +test
should run tests in scala 2.11 and scala 2.12.
Since last merge (scala.js branch) only 2.11 seems to be run.
Same issue occurs with sbt +publishSigned
.
Implement orEmpty for Option[T]
val stringOpt: Option[String] = None
stringOpt.orEmpty // ""
val intOpt: Option[Int] = None
intOpt.orEmpty // 0
val listOpt: Option[List[Int]] = None
listOpt.orEmpty // List()
Rename Validation.results to Validation.successes
To be more consistent
`sbt doc` not working anymore for hamster build
Command does not fail but no html is generated.
Make pattern matching possible in for-comprehensions using monad transformers
Current state of FutureOption
and FutureEither
does not allow pattern matching in for-comprehensions.
For example, the following wouldn't compile :
def foa: Future[Option[String]] = Future(Some(("a", 42)))
val composedAB: Future[Option[Int]] = (for {
(a, i) <- FutureOption(foa) if i > 5
} yield a).future
This would be solved by implementing withFilter
in both classes
Create a retry that accepts a function returning a Try
This method could be named Retry.fromTry
Then refactor retry to avoid code duplication.
Build Validation from List
Hello,
Is there a reason why we can not build a Validation from list through apply() method as
Validation(List(Ok, KO, KO))
Currently, I have to use Traditional approach with the new operator.
We could add the apply(l:List) in companion object of Validation class, what do you think about it ?
Many thanks for you help,
Fabrice
Find a way to define scaladoc on methods generated by macros
Scala 2.12 compatibility
Warning : Either is already right biased in scala 2.12
add to maven central
to enable usage in maven-projects, it would be really useful to add this library to maven central
Add Monad typeclass
To be able to make monad transformers work with more types
Retry.retry should be Retry.apply
Allow simpler type declaration for HLists
val hList : String :: Boolean :: HNil
should compile.
Currently only val hList : Hcons[String :: HCons[Boolean :: HNil]]
is working.
Macros not published for scala.js in the current build
Add an api to compute the cartesian product of n Option[T] (and other monad/applicative types)
Example :
val sum = (optionalInt1,optionalInt2).mapN((l, r) => l+r)
Maybe we could do something for Either, Validation, UnionType...
DefaultValue for Numeric is unsound
scala> implicitly[DefaultValue[BigDecimal]].get
java.lang.ClassCastException: java.lang.Integer cannot be cast to scala.math.BigDecimal
... 38 elided
You need to use the .zero
member of Numeric[T]
instead of trying to cast 0
.
Validation : Create a method that returns valid results even if there are some failures
Create a Validation compatible with Try monad
Validation.result(t1,t2, ...)
should accept Try[T] too. It could convert to Either[Throwable, T] internally.
Use macros to generate UnionN and UnionNType
We should use macros to generate union classes from 1 to n, n to be defined.
n should not be to high as t would not be convenient to pattern match.
Retry.withWait should use scala.concurrent.blocking
Hello all,
Thanks all for this lib, keep it up!
Retry.withWait
could wrap the Thread.sleep
inside a blocking
block, which warns the global execution context (so that it might add more threads).
Also I'd appreciate make it clearer in the docs that the method blocks a Thread.
Add a select method on Hlist
Like shapeless select on HList, it would be great to be able to select a value by type like
def select[U]
Add documentation for mapN
Documentation should explain how to use it with option and list and how to extend to other types with the right implicit definitions.
Simplify release process
It would be nice to be able to automatically :
- deploy to sonatype
- update Readme
- update REPL script to use the latest version
- create git tag
Hamsters REPL
Create a REPL with hamsters dependencies
Update scaladoc and Markdown documentation
Missing doc :
- Retry.fromTry & withWait
- NonEmptyList
- other classes/methods?
Find a way to retrieve types values of different types in Validation
In a Validation, there only 1 error type, but valid data can have different types.
It would be great to have a way to retrieve all valid data, for example something like :
val e1 = OK("1")
val e2 = OK(2)
val e3 = OK(3)
val validation = Validation(e1,e2, e3)
validation.map(_ + _ + _) // Validation("123")
validation.getOrElse("failure")//123
map
should be triggered only if all eithers are valid.
HList map and filter can't return a more precise type than HList
It's a problem if you need to type check the content of the resulting HList, for example if it's returned by a method.
So we may enhance the map/filter methods but only if it is possible to keep a (quite) simple HList model.
For more advanced Hlist features, people should use Shapeless instead.
In the same time, +++
private method in HCons could be removed in favor of ++
Plural form for result vs failures : rename to Validation.run
Validation.result vs Validation.failures. Use plural form for both
Edit : use rename Validation.result to Validation.run (see comments)
Publish a first release
First of all nice project. Could you please publish a first release eg. on bintray?
Typo in dependency
There is a typo in the dependency, it should be:
libraryDependencies ++= Seq(
"io.github.scala-hamsters" %% "hamsters" % "1.0.0-SNAPSHOT",
)
Implement typesafe equality
Scala.js Cross-Building
It would be nice to be able to use hamsters with Scala.js.
Case class <-> HList conversions
@Gen
case class User(firstName : String, lastName : String)
We could generate a companion object with methods :
implicit def toHlist(user) : String :: String :: HNil=???
implicit def fromHlist(v : String :: String :: HNil) : User=???
Generate def list of Enumerable with a macro
For now, you need to explicitly and manually write the following method
implicit val seasonEnumerable = new Enumerable[Season] {
override def list: List[Season] = List(Winter, Spring, Summer, Fall)
}
What's happen when i add another value.
If we generate this method with a macro (annotation vs def macros...), that could help.
scaladoc should not include scalameta doc
sbt doc generates html files for hamsters + scala meta
Add Enum typeclass
With list, toString, parse methods working with any case object
publishSigned not working with sbt 1.0
error : publish repository is undefined
See branch sbt_1_0
Dependency version incorrect in readme
The dependency version is not correct in the readme, it states:
libraryDependencies ++= Seq(
"io.github.scala-hamsters" %% "hamsters" % "1.0-BETA1"
)
but it should be:
libraryDependencies ++= Seq(
"io.github.scala-hamsters" %% "hamsters" % "1.0.0-BETA1"
)
Please change 1.0-BETA1 to 1.0**.0**-BETA1
Validation.results and Validation.failures have unconsistent types
The first one returns a list of Right types and the second one returns directly a List of errors (Left side type).
Define a more explicit error message when implicit execution context is missing for monad transformers
Current message : could not find implicit value for parameter evidence: io.github.hamsters.Monad[scala.concurrent.Future]
We should use @implicitNotFound to define a better one
Implements show for other types
Now show only supports String
and Int
.
We should support all the numeric primitives, java.util.Date
. java.time.*Date
...
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.