juan_gandhi: (Default)
object model {
  type MovieId = Long
  type UserId  = Long
  case class View(userId: UserId, movieId: MovieId)
}
import model._

object Solution extends App {
  def diverseMovies(views: Seq[View], numMovie: Int): Set[MovieId] = {
    def choose(except: Set[UserId] = Set.empty): MovieId = {
      views.collect { case view if !except(view.userId) => view }.
            groupBy(_.movieId).mapValues(_.size).maxBy(_._2)._1
    }
    
    def viewersOf(movie: MovieId) =
      views.filter(_.movieId equals movie).map(_.userId).toSet
    
    val result: (List[MovieId], Set[UserId]) =
      ((List.empty[MovieId], Set.empty[UserId])/:(1 to numMovie)) ({
        case ((movies: List[MovieId], ignoredUsers: Set[MovieId]), _) => {
          val movie = choose(ignoredUsers)
          (movie::movies, ignoredUsers ++ viewersOf(movie))
        }
      })
    result._1.toSet
      
  }
}
juan_gandhi: (Default)
 val Unit = () 
juan_gandhi: (Default)
Предположим, мы зафигачим такой класс:

sealed trait EitherTree[T] {
def map[U](f: T => U): EitherTree[U]
def flatMap[U](f: T => EitherTree[U]): EitherTree[U]
}

case class Right[T](v: T) extends EitherTree[T] {
def map[U](f: T => U): Right[U] = Right(f(v))

override def flatMap[U](f: T => EitherTree[U]): EitherTree[U] = f(v)
}

sealed trait Left[T] extends EitherTree[T] {
def map[U](f: T => U): Left[U]
def flatMap[U](f: T => EitherTree[U]): Left[U]
}

case class LeftLeaf[T](cause: Exception) extends Left[T] {
def map[U](f: T => U): LeftLeaf[U] = LeftLeaf[U](cause)

override def flatMap[U](f: T => EitherTree[U]): LeftLeaf[U] = LeftLeaf[U](cause)
}

case class LeftTree[T](first: Left[T], second: Left[T]) extends Left[T] {
def map[U](f: T => U): LeftTree[U] = LeftTree[U](first.map(f), second.map(f))

override def flatMap[U](f: T => EitherTree[U]): LeftTree[U] =
LeftTree[U](first.flatMap(f), second.flatMap(f))
}

Ну так чо, будет у нас монада?

Такое ощущение, что каждый скальщик будет горячо кивать головой.


juan_gandhi: (Default)
Scala Simplification Manifesto
  • Filtered colimits considered harmful
  • Free monads don't always exist
  • Free monads make code unrefactorable
  • Trampolining makes code untraceable and untestable
  • Kleisli is not a functor, it's a category, for a given monad
  • Type level programming makes code unmanageable (and unreadable)
  • Implicit transformations make code non-typesafe
  • cats.IO makes code unrefactorable
(feel free to add - or argue)
juan_gandhi: (Default)
Сегодня трахался с одной фигней. И вот код ходит куда-то на сервер, а приносит в ответ "неправильный json". Шо за json, я ничего такого не посылаю. А ошибка приходит. Стал изучать вопрос. А чо он неправильный, а там http4s берет какой-то Message[T], пытается из него сделать ByteBuffer, и обламывется, т.к. ByteBuffer оказывается пустой. Из чего он делается - Message состоит из каких-то Fragments; и вот один фрагмент пустой.

Что за фрагмент, чо он пустой, непонятно, но внутри его сидит SingleChunk, в котором сидит Chunk, и про него известно, что он пустой. Ну окей, ну покажите мне, что было-то. А не показывают. Там, конечно, цикл, но цикл навалян через рекурсию (типа так круче), а рекурсия оптимизирована через трамплин. В результате стектрейса нету, промежуточные данные не видны, Message не виден, потому что это макрос. А откуда вызвали, тоже непонятно, потому что трамплин, и весь стектрейс проебан.

И вот каким-то чудесным образом я где-то замечаю, что сервер-то послал HTTP 400. Ну правильно. И, конечно, в таком случае никакого джейсона. Но http4s на это все кладет с высокой колокольни, и начинает "парсить джейсон".

Ну на эту тему даже тест есть. Только этот тест не ловит HTTP 400, а ловит ошибку. Ага, ошибка! Ура. 

Такие дела.
 

А внутри cats, свободные монады, IO монада, завернутая в EitherT. 

А смысл?! Если HTTP 400 вы не ловите.

Что-то после раста все это смешно выглядит.

 

juan_gandhi: (Default)
Rust allows this, but Scala does not

fn main() {
let c = 'z';
let z = 'ℤ';
let heart_eyed_cat = '😻';
}


juan_gandhi: (Default)
And I got a feeling that after LambdaConf it looks pretty low-level and almost pathetic. Like Java 1 or something. Where's the progress? Where's deep insight? 
juan_gandhi: (Default)
Закончил свою логику. (Ну там тесты еще всю ночь побегут, но это фигня, мираж.)
juan_gandhi: (Default)
 def checkDistributivity(cat: Category): MatchResult[Any] = {
  val topos = new CategoryOfDiagrams(cat)
import topos._
val points = Ω.points

val desc = s"Testing ${cat.name} distributivity laws"
println(desc)

for { pt1 ← points } {
println(s" at ${pt1.tag}")
val p = predicateFor(pt1)

for { pt2 ← points } {
val q = predicateFor(pt2)
val pAndQ = p ∧ q
val pOrQ = p ∨ q

for { pt3 ← points } {
val r = predicateFor(pt3)
// distributivity of conjunction over disjunction
(p ∧ (q ∨ r)) === (pAndQ ∨ (p ∧ r))
// distributivity of disjunction over conjunction
(p ∨ (q ∧ r)) === (pOrQ ∧ (p ∨ r))
}
}
}

ok
}
juan_gandhi: (Default)

for { p <- Ω.points } {
val pp = predicateFor(p)
(True ∧ pp) === pp
(False ∧ pp) === False

// idempotence
(pp ∧ pp) === pp

for { q <- Ω.points } {
val pq = predicateFor(q)
val ppq = pp ∧ pq

// commutativity
(pp ∧ pq) === (pq ∧ pp)

for { r <- Ω.points } {
val pr = predicateFor(r)
// associativity
(ppq ∧ pr) === (pp ∧ (pq ∧ pr))
}
}
}

juan_gandhi: (Default)
Woke up at 4:20, went to fix my topos logic code. Done by 5:59. Happiness! 
juan_gandhi: (Default)
Программисты обсуждают тему, "Need help with calling and returning value from anon function in scala".

Несчастный страдалец пишет: "Can I in any way modify the code to not have a Future? I mean I need the response immediately and not in the future and using await is not an option here as I don't know the actual duration each request will take."

Ну и чо?
 Лечится? I don't think so. The guy is gone, I think.

 
juan_gandhi: (Default)
Here 

We have a list of unstarted futures; return a future that runs them one by one. Sequentially.
juan_gandhi: (Default)
Problem: given a list of pairs of nonnegative integers, where pairs represent edges of a directed graph, check if the graph is a linear order.

Solutions:
def isLinear(src: List[(Int, Int)]): Boolean = {
  val m = src.toMap.withDefaultValue(-1)
  val tails = m.values.toSet
  src.isEmpty || (src.size == m.size) && {
    src find { case (a,_) => !tails(a) } match {
      case Some((start,_)) =>
        val visited =
          Stream.iterate(start)(m).takeWhile(0 <=).take(src.size+2)
        visited.length == src.size + 1
      case None => false
    }
  }
}
juan_gandhi: (Default)
Reminds me what we did in Forth, with Leo, present here:

      applyTo | "a" | "b"  | "c" | "d"  | "e" |
      at("a") | "a" | "ab" | ""  | ""   | ""  |
      at("b") | ""  | "b"  | ""  | ""   | ""  |
      at("c") | ""  | "cb" | "c" | "cd" | ""  |
      at("d") | ""  | ""   | ""  | "d"  | ""  |
      at("e") | ""  | ""   | ""  | "ed" | "e" 


This is a test case. Rather, 25 test cases.
We scan through at("a") to at("e"), where at(x) is a representable diagram (presheaf, functor, whatever) for object x:
      val at = (obj: topos.site.Obj) => topos.representable(obj)


and then, in each row, apply this representable to objects "a",..., "e", and check that the result is a set (hom(x, y)) consisting of the values in the cells of the table. The values in the table are split by comma and converted to sets - because we deal with Grothendieck toposes.

But toposes are not essential here. I just decided to be lazy, and write code as tables, as Leo suggested eons ago, probably in 1989. It's not even my idea.

Implementation:
      val at = (obj: topos.site.Obj) => topos.representable(obj)
      
      case class table(data: List[String] = Nil) {
        def |(x: String): table = table(x::data)
        def |(d: Diagrams.Diagram) = check(d, data, data)
      }

      case class check(d: Diagram, data: List[String], fullList: List[String]) {
        def |(x: String): check = {
            d(data.head) === x.split(",").toSet
            check(d, data.tail, fullList)
        }
        def |(d: Diagram): check = check(d, fullList, fullList)
      }

      val applyTo = new table
juan_gandhi: (Default)









  def subsetOf(that: GenSet[A]): Boolean = this forall that


(that's GenSetLike[A,+Repr])

like

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

September 2025

S M T W T F S
 1 23456
78910111213
14151617181920
21222324252627
282930    

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 4th, 2025 06:26 am
Powered by Dreamwidth Studios