Skip to content

Instantly share code, notes, and snippets.

View p-pavel's full-sized avatar
💭
In pursuit for the meaning

Pavel Perikov p-pavel

💭
In pursuit for the meaning
View GitHub Profile
@p-pavel
p-pavel / TypeIndexing.scala
Created February 23, 2017 09:15
path dependent types and unapply
trait A {
type T
val t : T
}
object A {
def unapply(arg: A): Option[arg.T] = Some(arg.t)
}
def use(a : A) = a match {
@p-pavel
p-pavel / Elimination.scala
Last active February 25, 2017 13:06
Solving tagged types problem with elimination
/** Для решения проблемы с тем, что pattern matching в Scala теряет path dependent types
*
* @see [[https://gist.github.com/p-pavel/24e63bb9f40ea95fd988787a35ad4d80 this gist]]
* можно воспользоваться классикой -- introduce/eliminate
*/
object Elimination {
import language.higherKinds
@p-pavel
p-pavel / DirectBufferProg.scala
Created June 8, 2019 09:08
Свободные монады спешат на помощь
/*
О Свободной Алгебре.
--------------------
Возможно, кому-то это будет интересно, или даже проложит путь в Scala, которая умеет в котов.
Проблема: существует callback из внешнего мира, который передает нам DirectBuffer
DirectBuffer это, грубо говоря, кусок памяти. Он предоставляет удобные операции для доступа к этому куску.
Но сам кусок не будет валиден после возврата из коллбэка.
@p-pavel
p-pavel / DirectBufferProg.scala
Last active June 8, 2019 10:24
О свободных монадах
/*
О Свободной Алгебре.
--------------------
Возможно, кому-то это будет интересно, или даже проложит путь в Scala, которая умеет в котов.
Проблема: существует callback из внешнего мира, который передает нам DirectBuffer
DirectBuffer это, грубо говоря, кусок памяти. Он предоставляет удобные операции для доступа к этому куску.
Но сам кусок не будет валиден после возврата из коллбэка.
@p-pavel
p-pavel / UI.scala
Last active August 20, 2023 20:32
Входы-выходы и логика
trait IncrementDecrement[F[_]] { // Входы/выходы приложения инкремента-декремента
val increment: Stream[F,Unit] // Поток заявок на инкремент
val decrement: Stream[F,Unit] // Поток заявок на декремент
val total: Pipe[F,Int, INothing] // Переработка текущих значений в чистые побочные эффекты
}
object Logic {
import scala.concurrent.duration._
// Как работать с IncrementDecrement
def run[F[_]:Concurrent: Timer](app: IncrementDecrement[F]): Stream[F,INothing] = {
trait HList {
def ::[A](x: A): A :: this.type
}
trait ::[+Head, +Tail <: HList] extends HList {
val head: Head
val tail: Tail
def ::[A](x: A): A :: this.type = HCons(x,this)
}
final case class HCons[+Head, +Tail <: HList](head: Head, tail: Tail) extends (Head :: Tail) {
override def toString: String = s"$head :: $tail"
/**
* Не уверен, что это то, что нужно, но это самое общее решение
* Никак не опираемся на стандартную библиотеку
* У него, возможно или наверняка, будут проблемы с боксингом, но идея такая. Дальше можно
* запинать для производительности
*
* @see https://gist.github.com/p-pavel/2708ee0e7f5beac0a71551bfd885ef67
*/
object CustomCoercion {
// Тест текущего компилятора Scala3/Dotty и освоение возможностей
// Где взять, как пользоваться VSCode в качестве IDE и
// дока по языку -- здесь: https://dotty.epfl.ch/docs/index.html
/** Основыные алгебраические структур (без законов)
*/
object AlgebraicStructures {
trait Semigroup[T] {
def op(a: T, b: T): T
import scala.reflect.ClassTag
import scala.compiletime._
inline def alloc[T: ClassTag](n: Int) = if n > 0 then new Array[T](n) else error("Array size should be positive")
def main(args: Array[String]): Unit = {
println(alloc[Int](100).length)
alloc[Int](0) // не компилируется
}
enum Maybe[+A]:
case Just(a:A)
case None
given Functor[Maybe]:
def [A,B](fa: Maybe[A]).map(f: A ⇒ B): Maybe[B] =
import Maybe._
fa match
case Just(a) ⇒ Just(f(a))