juan_gandhi: (Default)
2010-09-18 07:27 pm

implicit: Int -> Category

(that's scala)

  /**
   * Builds a category out of a segment of integers between 0 and n (not included).
   *
   * @param n number of elements
   * @return a new category
   */
  implicit def segment(n:Int) : Category[Int, (Int, Int)] = Category(PoSet.range(0, n, 1))
//...

  def testImplicitSegment {
    def sut: Category[Int, (Int, Int)] = 3
    assertEquals(_3_, sut)
  }
juan_gandhi: (Default)
2010-09-07 02:10 pm
Entry tags:

now imagine

I badly need flatMap in my java code...
juan_gandhi: (Default)
2010-08-30 08:29 pm
Entry tags:

visitor pattern, scala sample


scala> abstract class N[T]                                                                                                                  
defined class N

scala> case class L[T](v:T) extends N[T]                                                                                 
defined class L

scala> case class B[T](kids:List[N[T]]) extends N[T]                                                                     
defined class B

scala> val t = B(List(B(List(L("ab"),L("cd"),B(List(L("xy"),L("z"))))),L("middle")))                                                        
t: B[java.lang.String] = B(List(B(List(L(ab), L(cd), B(List(L(xy), L(z))))), L(middle)))

scala> def scan[T](tree:N[T]):List[T] = tree match { case L(v) => List(v); case B(kids) => kids flatMap (scan(_)) } 
scan: [T](N[T])List[T]

scala> scan(t)                                                                                                                 
res17: List[java.lang.String] = List(ab, cd, xy, z, middle)

scala> 


I used repl, so it's kind of too laconic; in real life you probaly won't call your class N, L and B. But you know what I mean, right?
juan_gandhi: (Default)
2010-08-28 08:33 am
Entry tags:

visitor pattern

It's just pattern matching + monadic lifting. Omg. The problem was in language.[livejournal.com profile] kouzdra was right, all these patterns are just a set of dirty tricks that are good only when our language language is too bad.
juan_gandhi: (Default)
2010-07-21 09:59 pm
Entry tags:

hmm, second order generics...

  def product[X, T[_] <: Iterable[_]](xss:T[Set[X]]): Set[T[X]] =
      if (xss.isEmpty) {
        Set(T())
      } else {
        product(xss.first, xss.tail) map cat
      }


Not sure if it'll work. What happens here, we take type T, which is at least an Iterable, and build a product of T of sets; so it will be a set of Ts (kind of like monadic transformer, no? To me, it is a commutator), Set.T -> T.S; what I need from T is an empty constructor and a cat.

Will see.
juan_gandhi: (Default)
2010-07-15 10:31 am
Entry tags:

java question

(pls don't laugh)

So, really, in Java we cannot declare Functor, like in Scala?

trait Functor[F[_]] {
  def fmap[A, B](r: F[A], f: A => B): F[B]
}
juan_gandhi: (Default)
2010-05-15 11:04 am
Entry tags:

let me show you something

I was experimenting with Set[T] functor variance. Here are my considerations regarding the opportunity to make it contravariant. In short: it's impossible.

    /**
     * Casts a set into a set of subtype (contravariance, that is)
     * This method does not work, due to JVM type erasure.
     * Actually, delegating the work to runtime would be a stupid idea anyway;
     * so, is it a general problem with oop? Have to think.
     */
    @Deprecated  
    /*implicit*/ def downshift[A, B >: A] (source: Set[B]) : Set[A] = {
      val b2a: (B => A) = {case (a: A) => a}
      val elements = {for (b <- source; if b.isInstanceOf[A]) yield b2a(b)}
      setOf(elements, source.size, source.contains _)
    }


So, what I am thinking. Can we make Set functor contravariant in OOP? I mean, we have two problems here:

  1. Java type erasure makes it impossible to actually check the element type;

  2. OOP in general forces us to delegate this type checking to runtime - which is, I assume, a wrong idea



Seems like variance just does not work here.

I'll continue investigating the opportunities for covariance.
juan_gandhi: (Default)
2010-05-14 10:31 am
Entry tags:

lazypair again

Last night I've managed to write a class LazyPair where x is fixed and y is lazily calculated, via a given function.

Then I started thinking about variance. It is positive on y, but how about x? It is not so for x, since we have a function, and its argument should have negative variance. But I wrote in LazyPair definition that it implements Product2, that is, I'm saying it is "something like" a Cartesian product. So. If it is a Cartesian product, it should be covariant on both arguments.

So, whad do we have, given X and YX, and, of couse, we have X×YX → X×Y - but it is not a natural transformation. In short, bad luck. No functoriality. So I probably have to throw away the idea of lazy pair.

So there's a question regarding an adequate categorical interpretation of caching in general. I kind of can't figure out, how to deal with it.

In my specific case, in my code, I'll be replacing LazyPair[X, Y] with (X, X=>Y) (this means X×YX in Scala). But then thunk disappears. Something is wrong here.

Upd: thank you, [livejournal.com profile] huzhepidarasa! Got this stuff working:
  test("lazy pair should be covariant in first parameter") {
    val p: Product2[Int, Int] = LazyPair(123, (x:Int) => x * x)
    val q: Product2[Any, Int] = p
    expect(123) {q._1}
  }

  test("lazy pair should be covariant in second parameter") {
    val p: Product2[Int, Int] = LazyPair(8, (x:Int) => x * x)
    val q: Product2[Int, Any] = p
    expect(64) {q._2}
  }

  test("lazy pair assignment does not involve evaluation") {
    var n = 0;
    val p: Product2[Int, Int] = LazyPair(8, (x:Int) => {n = n + 1; x * x})
    expect(0){n}
    val q: Product2[Int, Any] = p
    expect(0){n}
    expect(64) {q._2}
    expect(1){n}
  }


(and thank you Martin for removing < from Scala!)
juan_gandhi: (Default)
2010-05-13 09:16 pm
Entry tags:

what do you think?

  case class LazyPair[X, Y](_1: X, f: X => Y) extends Product2[X, Y]
  {
    private lazy val y = f(_1)
    override def toString() = "(" + _1 + "," + _2 + ")"
    override def _2 = y
  }

  def lazyPair[X, Y](x: X, f: X => Y): Product2[X, Y] = new LazyPair(x, f)



The idea is, we won't call the function until we actually need it; and do it only once.

Note there's no variance in type parameters. I really do not know what to do about it, since the right variance would be [-X,+Y], and it does look stupid, no? Or maybe it does not.

Since it is case class, basically that's all we need.

Scala class Pair is actually Tuple2 which has tons of methods. I've lately came to a conclusion that we do not need most of the methods in most of the classes - e.g. Set[T] does not need size... and many other methods. Only have the right stuff.

Well, whatever. Just asking for your opinion.
juan_gandhi: (Default)
2010-04-22 07:56 am
Entry tags:

одностишие

scalar !!~ ((for(s <- "Hello Distributed World".split(' ')) yield(()=>println("***"+s+"***"))) 


Что тут происходит:
Берём строку, разбиваем её на подстроки, и для каждой подстроки возвращаем функцию без параметров, которая эту строку печатает на stdout, завернув в звёздочки.

Это всё действие не происходит так уж сразу, а оформляется как поток - когда попросили, тогда и вернули очередную функцию (монада, для понимающих).

Весь этот источник функций привинчивается оператором !!~ (по мне так было бы достаточно взять map) к scalar, представителю распределённой системы gridgain, который рассылает функции узлам, где попало, может быть, в разных уголках нашей маленькой планеты, где они гордо печатают свои тексты. Ну пример такой, вы ж понимаете.

Вчера всё это демонстрировал Никита Иванов на eBig, в ужасном Окленде.

А потом собравшиеся жжюзеры, [livejournal.com profile] _navi_, [livejournal.com profile] chrobin, я грешный, и некто Женя, жж не имеющий, ели в корейской барбекью - т.к. мы все опоздали на пиццу перед лекцией.

(А потом полчаса огородами пытались выехать из Окленда по алгоритму моего навигатора, слишком хорошо мне знакомому, т.к. я месяц отлаживал его аналог у себя на машине, пытаясь понять, на хрена вроде бы приличный многоуровневый двусторонний Дийкстра строит такой дебильный маршрут. Видно, это Окленд наводит порчу. Например, из Бони Дуна в Лос Гатос тот алгоритм вообще дорогу не находит.