Last active
March 29, 2020 17:35
-
-
Save p-pavel/bfad86676e7dde026cfafab1b1b36b7c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Тест текущего компилятора Scala3/Dotty и освоение возможностей | |
// Где взять, как пользоваться VSCode в качестве IDE и | |
// дока по языку -- здесь: https://dotty.epfl.ch/docs/index.html | |
/** Основыные алгебраические структур (без законов) | |
*/ | |
object AlgebraicStructures { | |
trait Semigroup[T] { | |
def op(a: T, b: T): T | |
} | |
trait CommutativeSemigroup[T] extends Semigroup[T] // Laws only | |
trait Monoid[T] extends Semigroup[T] { | |
def id: T | |
} | |
trait Group[T] extends Monoid[T] { | |
def inverse(a: T): T | |
} | |
trait CommutativeMonoid[T] extends Monoid[T] with CommutativeSemigroup[T] | |
trait AbelianGroup[T] extends Group[T] with CommutativeMonoid[T] | |
trait Semiring[T] { | |
val additive: CommutativeMonoid[T] | |
val multiplicative: Monoid[T] | |
} | |
trait CommutativeSemiring[T] extends Semiring[T] { | |
val multiplicative: CommutativeMonoid[T] | |
} | |
trait Ring[T] extends Semiring[T] { | |
val additive: AbelianGroup[T] | |
} | |
trait CommutativeRing[T] extends Ring[T] with CommutativeSemiring[T] | |
trait Field[T] extends CommutativeRing[T] { | |
val multiplicative: AbelianGroup[T] // excluding zero :( | |
} | |
} | |
/** Удобный синтаксис */ | |
object AlgebraicSyntax { | |
import AlgebraicStructures._ | |
inline def [T](a: T).negate(using r: Ring[T]): T = r.additive.inverse(a) | |
inline def zero[T](using r: Semiring[T]): T = r.additive.id | |
inline def one[T](using r: Semiring[T]): T = r.multiplicative.id | |
inline def [T](a: T).+(b: T)(using r: Semiring[T]): T = r.additive.op(a,b) | |
inline def [T](a: T).*(b: T)(using r: Semiring[T]): T = r.multiplicative.op(a,b) | |
inline def [T](a: T).-(b: T)(using r: Ring[T]): T = a + r.additive.inverse(b) | |
inline def [T](a: T).reciprocal(using r: Field[T]): T = r.multiplicative.inverse(a) | |
inline def [T](a: T)./(b: T)(using r: Field[T]): T = a * b.reciprocal; | |
} | |
/** Понятие действительных и комплексных чисел */ | |
object Numbers { | |
import AlgebraicStructures._ | |
type RealNumber[T] = Field[T] & Ordering[T] | |
final case class Complex[T] (val re: T, val im: T )(using isReal: => RealNumber[T]) | |
/** Поле комплексных чисел */ | |
trait ComplexField[T: RealNumber] extends Field[Complex[T]] { | |
type Carrier = Complex[T] | |
import AlgebraicSyntax._ | |
object additive extends AbelianGroup[Carrier] { | |
def inverse(a: Carrier) = Complex(a.re.negate, a.im.negate) | |
def id: Carrier = Complex(zero,zero) | |
def op(a: Carrier, b: Carrier) = Complex(a.re + b.re, a.im + b.im) | |
} | |
object multiplicative extends AbelianGroup[Carrier] { | |
def id: Carrier = Complex(one, zero) | |
def op(a: Carrier, b: Carrier) = Complex(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re) | |
def inverse(a: Carrier) = { | |
val denom = a.re * a.re + a.im * a.im | |
Complex(a.re / denom, (a.im / denom).negate) | |
} | |
} | |
} | |
given [T: RealNumber] as Field[Complex[T]] = new ComplexField[T] {} | |
} | |
object VectorFields { | |
import AlgebraicStructures._ | |
trait VectorField[Scalar, T] extends Field[Scalar] with AbelianGroup[T] { | |
def scalaMul(a: Scalar, t: T): T | |
} | |
} | |
/** Связь между числами и типами, реализующими Numeric и Fractional (включая встроенные) */ | |
object NumericStructures { | |
import AlgebraicStructures._ | |
import Numbers._ | |
trait AdditiveAbelianGroupOnNumeric[T] (using n: Numeric[T]) extends AbelianGroup[T] { | |
def inverse(a: T): T = n.negate(a) | |
def id: T = n.fromInt(0) | |
def op(a: T, b: T): T = n.plus(a,b) | |
} | |
trait MultiplicativeCommutativeMonoidOnNumeric[T] (using n: Numeric[T]) extends CommutativeMonoid[T] { | |
def id: T = n.fromInt(1) | |
def op(a: T, b: T): T = n.times(a,b) | |
} | |
class MultiplicativeAbelianGroupOnFractional[T] (using f: Fractional[T]) | |
extends MultiplicativeCommutativeMonoidOnNumeric[T] with AbelianGroup[T] | |
{ | |
def inverse(a: T) = f.div(f.one,a) | |
} | |
trait NumericCommutativeRing[T: Numeric] extends CommutativeRing[T]{ | |
val additive = new AdditiveAbelianGroupOnNumeric[T] {} | |
val multiplicative = new MultiplicativeCommutativeMonoidOnNumeric[T] {} | |
} | |
trait FractionalField[T: Fractional] extends Field[T]{ | |
val additive = new AdditiveAbelianGroupOnNumeric[T] {} | |
val multiplicative = new MultiplicativeAbelianGroupOnFractional[T] | |
} | |
trait FractionalOrdering[T: Fractional] extends Ordering[T]{ | |
private val default: Ordering[T] = summon | |
def compare(a: T, b: T): Int = default.compare(a,b) | |
} | |
// Все Numeric образуют коммутативное кольцо | |
given [T: Numeric] as CommutativeRing[T] = new NumericCommutativeRing[T] {} | |
// Все Fractional образуют поле | |
given [T: Fractional] as RealNumber[T] = new FractionalField[T] with FractionalOrdering[T] {} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment