• Stars
    star
    120
  • Rank 295,983 (Top 6 %)
  • Language
    Scala
  • License
    Apache License 2.0
  • Created about 9 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Tiny independent libraries with a single purpose, often a single class

scala-common

Join the chat at https://gitter.im/softwaremill/scala-common CI

Tiny independent libraries with a single purpose, often a single class. Available for Scala 2.11, 2.12, 2.13, 3; JVM and JS.

Tagging

Maven Central

Tag instances with arbitrary types. Useful if you'd like to differentiate between instances on the type level without runtime overhead. Tags are only used at compile-time to provide additional type safety.

An instance of type T tagged with type U has type T @@ U (which is sugar for @@[T, U]). You can only use x: T @@ U when an instance of type T @@ V is expected when U is a subtype of V (U <: V).

The tag can be any type, but usually it is just an empty marker trait.

To add tags to existing instances, you can use the taggedWith[_] method, which returns a tagged instance (T.taggedWith[U]: T @@ U). Tagged instances can be used as regular ones, without any constraints.

SBT dependency:

libraryDependencies += "com.softwaremill.common" %% "tagging" % "2.3.4"

Example:

import com.softwaremill.tagging._

class Berry()

trait Black
trait Blue

val berry = new Berry()
val blackBerry: Berry @@ Black = berry.taggedWith[Black]
val blueBerry: Berry @@ Blue = berry.taggedWith[Blue]

// compile error: val anotherBlackBerry: Berry @@ Black = blueBerry

Original idea by Miles Sabin. Similar implementations are also available in Shapeless and Scalaz.

Tagging and typeclasses

Let's consider the following example:

import com.softwaremill.tagging._

// Our typeclass
trait Serializer[T] {
  def doSerialize(t: T): String
}

// Method that leverages typeclass, to transform some T into a String
def serialize[T](t: T)(implicit ser: Serializer[T]): String = {
  ser.doSerialize(t)
}

// Typeclass instance for type `Long`
implicit val longSerializer = new Serializer[Long] {
  override def doSerialize(t: Long): String = "Long number: " + t
}

val longNumber = 30L
serialize(longNumber) // Compiles and returns "Long number: 30"

// Our marker trait to be used as a tag
trait UserId

val id: Long @@ UserId = 1024L.taggedWith[UserId]
serialize(id) // Won't compile: could not find implicit value for parameter ser

Because tagged type T @@ U is considered by the compiler as a different type than T, it will complain about missing implicit typeclass Serializer[_] for T @@ U, even if there is instance of Serializer[T] already in scope.

To solve this problem just either mix-in TypeclassTaggingCompat[M[_]]/AnyTypeclassTaggingCompat trait or import contents of the AnyTypeclassTaggingCompat object:

import com.softwaremill.tagging.AnyTypeclassTaggingCompat._

serialize(id) // Compiles and returns "Long number: 1024"

TypeclassTaggingCompat brings implicit conversion, that can adapt any implicit M[T] to be used as M[T @@ U].

Future Try extensions

Maven Central

Provides two utility methods for extending Future:

  • tried: Future[Try[T]] - reifying the Future's result.
  • transformTry(f: Try[T] => Try[S]): Future[S] - corresponds to 2.12's new transform variant, allowing to supply a single function (if, for example, you already have one handy), instead of two. Note: unfortunately, it was not possible to name this method transform, due to how scalac handles implicit resolution.

SBT depedency:

libraryDependencies += "com.softwaremill.common" %% "futuretry" % "1.0.1"

Example:

val myFuture: Future[Foo] = ...
val myUsefulTransformer: Try[Foo] => Try[Bar] = ...

def someWeirdApiMethod(future: Future[Try[Foo]])
 
import com.softwaremill.futuretry._

someWeirdApiMethod(myFuture.tried)

val myBetterFuture: Future[Bar] = myFuture.transformTry(myUsefulTransformer)

Future Squash

Maven Central

Goal

Monad stacks are not easy to compose (e.g. in a for comprehension), and if you don't want to use Monad transformers you can use this Future additional methods.

FutureSquash.fromEither

import com.softwaremill.futuresquash.FutureSquash

FutureSquash.fromEither(Right("a")) //Future("a")
FutureSquash.fromEither(Left(BoomError)) //Future(BoomError)

squash Future[Either[Throwable, A]] and Future[Try[A]]

You can use squash on a Future[Either[Throwable, A]] to get a Future[A].

import FutureSquash._

abstract class Error(message: String) extends Exception(message)
case object BoomError extends Error("Boom")

val fea: Future[Either[Error, String]] = Future(Right("a"))
val feb: Future[Either[Error, String]] = Future(Left(BoomError))

fea.squash //Future("a")
feb.squash //Future(BoomError)

You can also squash on a Future[Try[A]] to get a Future[A] in much the same way:

import FutureSquash._

val fta: Future[Try[String]] = Future(Success("a"))
val ftb: Future[Try[String]] = Future(Failure(new Exception("Boom")))

fta.squash //Future("a")
ftb.squash //Future(Exception("Boom"))

It can also be useful to compose several Future[Either[Throwable, _]] without monad transformers :

def fea: Future[Either[Throwable, Int]] = Future(Right(1))
def feb(a: Int): Future[Either[Throwable, Int]] = Future(Right(a + 2))

val composedAB: Future[Int] = for {
  a <- fea.squash
  ab <- feb(a).squash
} yield ab

composedAB // Future("ab")

val error: Either[Throwable, Int] = Left(BoomError)
val composedABWithError: Future[Int] = for {
  a <- Future.successful(error).squash
  ab <- feb(a).squash
} yield ab

composedABWithError //Future(Failure(BoomError))

Composing several Future[Try[_]]s without monad transformers is also possible:

def fta: Future[Try[Int]] = Future(Success(1))
def ftb(a: Int): Future[Try[Int]] = Future(Success(a + 2))

val composedAB: Future[Int] = for {
  a <- fta.squash
  ab <- ftb(a).squash
} yield ab

composedAB // Future("ab")

Options

Same operations can be used with options : FutureSquash.fromOption and squash on Future[Option[A]]. For empty options, an EmptyValueError will be raised.

Either additional operations (EitherOps)

Maven Central

This small util methods allow to use Either for multiple values validation, to avoid for comprehension fail-fast behavior and accumulate errors.

Example :

import com.softwaremill.eitherops._

case class Person(firstName: String, lastName: String, age: Int)

sealed trait Error
case class NumericError(message: String) extends Error
case class OtherError(message: String) extends Error

def validateAge(intValue: Int): Either[NumericError, Int] = ??? 
def validateFirstName(stringValue: String): Either[OtherError, String] = ???
def validateLastName(stringValue: String): Either[OtherError, String] = ???

val errors: Seq[Error] = EitherOps.collectLefts(
  validateFirstName("john"),
  validateLastName("doe"),
  validateAge(40)
)

if (errors.isEmpty) ???// use for comprehension here to build a Person 
else ??? // handle errors here

EitherOpscollectRights symmetric method is provided for convenience.

Simple benchmarking utilities

Maven Central

Provides utilities for benchmarking.

  • Timed.runTests(tests: List[(String, () => String)], repetitions: Int): runs specified number of repetitions of given code blocks and collects results (mean and standard deviation). A warmup round of all tests will be executed before measuring any statistics. Tests will be executed in random order.

  • Timed.runTests(tests, repetitions, warmup) runs multiple repetitions of shuffled tests provided as a list of PerfTest instances. Each PerfTest should define a name, body (synchronous code block) and, optionally, an additional code block that specifies a "warmup" that will be run before each test execution. The Timed object can also consume an optional warmup argument which specified code block that should be executed before all tests. If omitted, the default global warmup will run all the provided tests once (without collecting metrics).

Example:

val simpleTests: List[(String, () => String)] = List(
  ("test1", () => {
    // do some calculation
    "Ok"
  }),
  ("test2", () => {
    // do some other calculation
    "Ok"
  })
)

Timed.runTests(simpleTests, repetitions = 50)

or

case class MyTest(name: String, param: Int) extends PerfTest {

  override def warmup(): Unit = {
    // prepare some resources
  }

  override def run(): Try[String] = {
    // do some calculations
    Success(String)
  }
}
  
val tests: List[MyTest] = List(
  MyTest("test1", param = 665), MyTest("test2", param = 777)    
)
  
Timed.runTests(tests, repetitions = 50, warmup = (tests: List[MyTest]) => {
  // global warmup body
})

More Repositories

1

elasticmq

In-memory message queue with an Amazon SQS-compatible interface. Runs stand-alone or embedded.
Scala
2,502
star
2

sttp

The Scala HTTP client you always wanted!
Scala
1,454
star
3

tapir

Rapid development of self-documenting APIs
Scala
1,363
star
4

macwire

Zero-cost, compile-time, type-safe dependency injection library.
Scala
1,266
star
5

quicklens

Modify deeply nested case class fields
Scala
822
star
6

magnolia

Easy, fast, transparent generic derivation of typeclass instances
Scala
765
star
7

bootzooka

Simple project to quickly start developing a Scala-based microservice or web application, without the need to write login, user registration etc.
Scala
695
star
8

codebrag

Your daily code review tool
Scala
651
star
9

akka-http-session

Web & mobile client-side akka-http sessions, with optional JWT support
Scala
440
star
10

ox

Safe direct-style concurrency and resiliency for Scala on the JVM
Scala
382
star
11

it-cfp-list

List of Call For Papers for IT conferences
374
star
12

retry

because you should never give up, at least not on the first try
Scala
351
star
13

diffx

Pretty diffs for scala case classes
Scala
344
star
14

kmq

Kafka-based message queue
Scala
330
star
15

scala-clippy

Good advice for Scala compiler errors
Scala
315
star
16

supler

Rapid Form Development library. Use your favourite JS frontend & Scala backend frameworks.
Scala
286
star
17

jox

Fast and Scalable Channels in Java
Java
248
star
18

mqperf

Scala
144
star
19

slick-eventsourcing

Example for "Entry level event-sourcing" blog
Scala
118
star
20

lemon-dataset

Lemons quality control dataset
103
star
21

maven-badges

A node.js implementation of https://github.com/jirutka/maven-badges, originally created in ruby.
TypeScript
86
star
22

sbt-softwaremill

A sane set of default build settings
Scala
72
star
23

akka-vs-scalaz

Scala
63
star
24

recursion-training

Recursion schemes training examples and exercises
HTML
59
star
25

livestub

The HTTP server stub you always wanted!
Scala
53
star
26

scala-sql-compare

Scala
50
star
27

stringmask

A micro-library for macro-based case class field masking in .toString
Scala
48
star
28

scala-id-generator

Scala
48
star
29

confluent-playground

Java
44
star
30

sttp-model

Simple Scala HTTP model
Scala
43
star
31

odelay

delayed reactions
Scala
42
star
32

saft

Scala
42
star
33

sttp-openai

Scala
41
star
34

akka-simple-cluster-k8s

Scala
39
star
35

walk-that-type

A tool for evaluating TypeScript types step by step.
TypeScript
39
star
36

softwaremill-common

SoftwareMill Common library
Java
37
star
37

OtterJet

Visualization of messages from a NATS JetStream server
Java
33
star
38

scala-pre-commit-hooks

Pre-commit/Pre-push hooks for Scala
Python
32
star
39

FoXAI

The open-source library for explainable AI. Generic and easy to integrate with PyTorch.
Python
31
star
40

neme-plugin

Scala compiler plugin for turning non exhaustive match warnings into errors
Scala
29
star
41

reactive-event-sourcing-java

Java
28
star
42

zio2-structure

Scala
26
star
43

helisa

Scala API for jenetics
Scala
26
star
44

streams-tests

Scala
25
star
45

meerkat

Observability Starter Kit for JVM Applications
JavaScript
25
star
46

tapir-loom

Scala
24
star
47

sttp-apispec

OpenAPI, AsyncAPI and JSON Schema Scala models.
Scala
23
star
48

node-typescript-starter

A basic boilerplate for node + TypeScript development with debugger source maps support.
TypeScript
22
star
49

free-tagless-compare

Free monads compared to tagless final
Scala
22
star
50

akka-http-session-faq

Java
21
star
51

activator-reactive-kafka-scala

Activator template for Reactive Kafka
Scala
20
star
52

adopt-tapir

A quickstart generator for Tapir projects
Scala
17
star
53

reactive-streams-for-java-developers

Java
17
star
54

scala3-macro-debug

Scala
17
star
55

resilience4s

Scala
16
star
56

react-use-promise-matcher

React hooks allowing you to handle promises in a stateful way
TypeScript
16
star
57

simple-http-server

Simple JVM based HTTP server with no dependencies
Scala
15
star
58

correlator

Scala
15
star
59

detectnet-tests

Python scripts and other resources for tesing DetectNet on Nvidia DIGITS
Python
14
star
60

blockchain-schedule

An experimental collaborative planning app based on Ethereum ("Decentralized Doodle")
TypeScript
14
star
61

blog-scala-structure-lifecycle

Scala
12
star
62

akka-sandbox

Training ground for experiments with Akka framework.
Scala
12
star
63

broadway-pipelines-blog

Constructing effective data processing workflows using Elixir and Broadway
Elixir
12
star
64

undelay

Satisfy Scala Futures quickly
Scala
11
star
65

monix-correlation-id

Scala
10
star
66

cassandra-monitoring

Scripts for the Cassandra Monitoring blog miniseries
10
star
67

reason-companies-example

Reason example application
OCaml
10
star
68

jvmbot

Scala
9
star
69

botarium

A simple starter kit for building bots using Node + TypeScript + BotKit.
TypeScript
8
star
70

sbt-template

Scala
8
star
71

asamal

POC for a CDI-based web lightweight framework
Java
8
star
72

boot-scala-microservice

Bootstrap microservice template that uses micro-deps library https://github.com/4finance/micro-deps
Scala
8
star
73

sttp-shared

Scala
7
star
74

modem-connector

Modulator and Demodulator for HAM Radio AX.25 audio signals
Scala
7
star
75

vehicle-routing-problem-java

Java
6
star
76

idea-pastie-plugin

Plugin to post pastie.org pasties from IntelliJ Idea
Java
5
star
77

trqbox-demo

Ruby
5
star
78

sentinel-cgan

Sentinel generative conditional adversarial network implementation
Python
5
star
79

scalatimes

Pug
5
star
80

tapir-serverless

Scala
5
star
81

scala-compiler-plugin-template

Scala
5
star
82

gatling-zeromq

A Gatling stress test plugin for ZeroMQ protocol
Scala
5
star
83

slack-alphabet

Scala
4
star
84

scalar-conf-website

Scalar - Scala Conference in Central Europe
Python
4
star
85

try-them-off

Showcase service presenting possible usage of the Try monad from Vavr.
Java
4
star
86

sttp-openapi-example

Scala
4
star
87

cache-get-or-create

Java
4
star
88

bootzooka-react

Simple project to quickly start developing a web application using React and Akka HTTP, without the need to write login, user registration etc. https://softwaremill.com/open-source/
Scala
4
star
89

fabrica

Shell
3
star
90

akka-typed-workshop

Scala
3
star
91

kuberenetes-fundamentals

Training projects to explore k8s features
Scala
3
star
92

oauth_tutorial

Phoenix OAuth tutorial
Elixir
3
star
93

terraform-gke-bootstrap

HCL
3
star
94

sttp-native-cli

Scala Native with scala-cli and sttp example
Scala
3
star
95

functional-pancakes

Scala
3
star
96

play-scala-slick-example-part2

Scala
3
star
97

ansible-bigbluebutton

Shell
3
star
98

kleisli-example

Scala
3
star
99

loom-protect

Java
3
star
100

supler-example

Example project for Supler http://supler.io
JavaScript
2
star