singleton-ops


License

License

GroupId

GroupId

eu.timepit
ArtifactId

ArtifactId

singleton-ops_2.13
Last Version

Last Version

0.5.2
Release Date

Release Date

Type

Type

jar
Description

Description

singleton-ops
singleton-ops
Project URL

Project URL

https://github.com/fthomas/singleton-ops
Project Organization

Project Organization

eu.timepit
Source Code Management

Source Code Management

https://github.com/fthomas/singleton-ops

Download singleton-ops_2.13

How to add to project

<!-- https://jarcasting.com/artifacts/eu.timepit/singleton-ops_2.13/ -->
<dependency>
    <groupId>eu.timepit</groupId>
    <artifactId>singleton-ops_2.13</artifactId>
    <version>0.5.2</version>
</dependency>
// https://jarcasting.com/artifacts/eu.timepit/singleton-ops_2.13/
implementation 'eu.timepit:singleton-ops_2.13:0.5.2'
// https://jarcasting.com/artifacts/eu.timepit/singleton-ops_2.13/
implementation ("eu.timepit:singleton-ops_2.13:0.5.2")
'eu.timepit:singleton-ops_2.13:jar:0.5.2'
<dependency org="eu.timepit" name="singleton-ops_2.13" rev="0.5.2">
  <artifact name="singleton-ops_2.13" type="jar" />
</dependency>
@Grapes(
@Grab(group='eu.timepit', module='singleton-ops_2.13', version='0.5.2')
)
libraryDependencies += "eu.timepit" % "singleton-ops_2.13" % "0.5.2"
[eu.timepit/singleton-ops_2.13 "0.5.2"]

Dependencies

compile (3)

Group / Artifact Type Version
org.scala-lang : scala-compiler jar 2.13.1
org.scala-lang : scala-library jar 2.13.1
com.chuusai : shapeless_2.13 jar 2.3.3

test (1)

Group / Artifact Type Version
org.scalacheck : scalacheck_2.13 jar 1.14.3

Project Modules

There are no modules declared in this project.

singleton-ops

Build Status codecov Join the chat at https://gitter.im/fthomas/singleton-ops Scaladex Scala.js

This library provides type-level operations for Typelevel Scala with SIP-23.

Simple example:

import singleton.ops._

class MyVec[L] {
  def doubleSize = new MyVec[2 * L]
  def nSize[N] = new MyVec[N * L]
  def getLength(implicit length : SafeInt[L]) : Int = length
}
object MyVec {
  implicit def apply[L](implicit check : Require[L > 0]) : MyVec[L] = new MyVec[L]()
}
val myVec : MyVec[10] = MyVec[4 + 1].doubleSize
val myBadVec = MyVec[-1] //fails compilation, as required

Using singleton-ops

The latest version of the library is 0.5.0, which is available for Scala versions 2.11.12, 2.12.8, and 2.13.1.

If you're using sbt, add the following to your build:

libraryDependencies ++= Seq(
  "eu.timepit" %% "singleton-ops" % "0.5.0"
)

If you're using scala.js use %%% instead

libraryDependencies ++= Seq(
  "eu.timepit" %%% "singleton-ops" % "0.5.0"
)

Be sure to follow Typelevel Scala instructions, to be able to use literal types in your code.


Supported types:

  • Char with Singleton (aliased as XChar)
  • Int with Singleton (aliased as XInt)
  • Long with Singleton (aliased as XLong)
  • Float with Singleton (aliased as XFloat)
  • Double with Singleton (aliased as XDouble)
  • String with Singleton (aliased as XString)
  • Boolean with Singleton (aliased as XBoolean)
  • Nat (from Shapeless)

Supported arithmetic operations:

  • type +[P1, P2]
  • type -[P1, P2]
  • type *[P1, P2]
  • type /[P1, P2]
  • type %[P1, P2]
  • type Abs[P1]
  • type Negate[P1]

Supported relational operations:

  • type ==[P1, P2]
  • type !=[P1, P2]
  • type >[P1, P2]
  • type <[P1, P2]
  • type >=[P1, P2]
  • type <=[P1, P2]
  • type Min[P1, P2]
  • type Max[P1, P2]

Supported logical operations:

  • type &&[P1, P2]
  • type ||[P1, P2]
  • type ![P1]

Supported explicit conversion operations:

  • type ToNat[P1]
  • type ToChar[P1]
  • type ToInt[P1]
  • type ToLong[P1]
  • type ToFloat[P1]
  • type ToDouble[P1]
  • type ToString[P1]

Supported string operations:

  • type Length[S]
  • type +[S1, S2] (concat)
  • type Reverse[S]
  • type CharAt[S, I]
  • type Substring[S, I]
  • type SubSequence[S, IBeg, IEnd]
  • type StartsWith[S, Prefix]
  • type EndsWith[S, Suffix]
  • type Head[S]
  • type Tail[S]
  • type Matches[S, Regex]
  • type FirstMatch[S, Regex]
  • type PrefixMatch[S, Regex]
  • type ReplaceFirstMatch[S, Regex, R]
  • type ReplaceAllMatches[S, Regex, R]

Supported constraints operations:

  • type Require[P1]

Supported control operations:

  • type ==>[A, B] (first A then B)
  • type ITE[I,T,E] (If (I) Then (T) Else (E))

Supported Aux Pattern interface:

  • type OpAuxNat[O <: Op, Ret_Out <: Nat]
  • type OpAuxChar[O <: Op, Ret_Out <: XChar]
  • type OpAuxInt[O <: Op, Ret_Out <: XInt]
  • type OpAuxLong[O <: Op, Ret_Out <: XLong]
  • type OpAuxFloat[O <: Op, Ret_Out <: XFloat]
  • type OpAuxDouble[O <: Op, Ret_Out <: XDouble]
  • type OpAuxString[O <: Op, Ret_Out <: XString]
  • type OpAuxBoolean[O <: Op, Ret_Out <: XBoolean]

Examples

  • Int type operations:
import singleton.ops._
def demo[L <: XInt](implicit p : L*L + L) : p.Out = p.value
val b : 30 = demo[5]
  • Long type operations:
import singleton.ops._
def demoLong[L1 <: XLong, L2 <: XLong](implicit p : Min[L1*L1, L2+L2]) : p.Out = p.value
val bLong1 : 1L = demoLong[1L, 5L]
val bLong2 : 6L = demoLong[3L, 3L]
  • Double type operations:
import singleton.ops._
def demoDouble[L1 <: XDouble, L2 <: XDouble](implicit p : L1 / L2 + 1.0) : p.Out = p.value
val bDouble : 1.2 = demoDouble[1.0, 5.0]
  • Combined Long and Int type operations:
import singleton.ops._
def demoSumLongInt[L1 <: XLong, L2 <: XInt](implicit p : L1 + L2) : p.Out = p.value
val bSumLongInt : 16L = demoSumLongInt[8L, 8]
  • String type operations:
import singleton.ops._
def demoString[P1 <: XString](implicit op : Reverse[P1] + P1) : op.Out = op.value
val bString : "cbaabc" = demoString["abc"]
  • Boolean type operations:
import singleton.ops._
def demoBoolean[P1 <: XInt](implicit op : P1 < 0) : op.Out = op.value
val bBoolean1 : true = demoBoolean[-5]
val bBoolean2 : false = demoBoolean[5]
val bBoolean3 : false = demoBoolean[0]
  • Boolean type constraints:
import singleton.ops._
def demoRequire[P1 <: XInt](implicit op : Require[P1 < 0]) : op.Out = op.value
scala> demoRequire[-1]
demoRequire[-1]
res0: Boolean(true) = true
scala> demoRequire[1]
<console>:16: error: could not find implicit Out for parameter op: singleton.ops.Require[singleton.ops.<[1,0]]
       demoRequire[1]
  • Shapeless' Nat type operations:
import singleton.ops._
import shapeless._
val n = Nat(5)
//Converting Nat to Int singleton occurs implicitly
def demoNatToSing[L <: Nat](implicit p : L+L) : p.Out = p.value
val bSing10 : 10 = demoNatToSing[n.N]
//Converting Int singleton to Nat requires explicit `ToNat`
def demoSingToNat[L <: XInt](implicit op : ToNat[L+L]) : op.Out = op.value
val bNat10 : shapeless.nat._10 = demoSingToNat[5]
  • Working with large numbers doesn't slay the compiler:
import singleton.ops._
def bigMul[L1 <: XLong, L2 <: XLong](implicit p : L1 * L2) : p.Out = p.value
scala> bigMul[32000L, 6400000L]
res2: Long = 204800000000

Contributors and participation

The singleton-ops project supports the Typelevel code of conduct and wants all of its channels (Gitter, GitHub, etc.) to be welcoming environments for everyone.

Versions

Version
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0