scala> type λ = Any; type λλ=λ=>λ; type λλλ=λ=>λλ;
defined type alias λ
defined type alias λλ
defined type alias λλλ
scala> val I:λλ = (x:λ)=>x
I: λ => λ = <function1>
scala> val K:λλλ = (x:λ)=>(y:λ)=>x
K: λ => (λ => λ) = <function1>
scala> val S = (x:λλλ)=>(y:λλ)=>(z:λ)=>x(z)(y(z))
S: (λ => (λ => λ)) => ((λ => λ) => (λ => λ)) = <function1>
Понятно, что скала никуда не пустит
funny scala question
Feb. 28th, 2015 09:27 pm(from Scala maillist)
"Another, possibly related issue:
This has a problem with the '*' in 'x * x' ... complaint is 'Cannot resolve symbol '*''.
Now *that* is fussy.
What is happening?"
"Another, possibly related issue:
class StrangeIntQueue extends Queue[Int] { override def enqueue[Int](x:Int) = { println( x * x ) super.enqueue(x).asInstanceOf[Queue[Int]] } }
This has a problem with the '*' in 'x * x' ... complaint is 'Cannot resolve symbol '*''.
Now *that* is fussy.
What is happening?"
funny code I found
Jan. 12th, 2015 11:34 amdef toSource(x: Any): String = { x match { case null => "null" case s: String => "\"" + s.replaceAll("\"", "\\\"") + "\"" case list:List[_] => "List(" + list.map(toSource).mkString(", ") + ")" case array:Array[_] => "Array(" + array.map(toSource).mkString(", ") + ")" case map:Map[_, _] => "Map(" + map.map{case(k,v) => toSource(k) + "->" + toSource(v)}.mkString(", ") + ")" case other => other.toString } }
а вот и весь мой рендеринг
Dec. 5th, 2014 05:00 pmdef questionHTML(i: Int, q: String) = <span> <h3>Question {i+1}</h3>{q} <br/><br/><br/><br/><br/><br/> </span> def variantHTML(v: List[String]) = <p style="page-break-after:always;"> <h1><center>{title}</center></h1> {v.zipWithIndex map {case(q,j) => questionHTML(j,q)}} </p> def html(variants: List[List[String]]) = { <html><body>{ variants map variantHTML }</body></html> }
навалял в духе проекта Эйлер
Dec. 5th, 2014 03:53 pmКороче, есть, скажем, пять вопросов для экзамена, каждый в нескольких вариантах; задача - изготовить варианты, чтобы они максимально различались. Ну типа всех возможных будет 55, а мне надо 27, ну вот взять первые 27 из таких.
С таким смаком навалял это на скале. Типа такого:
С таким смаком навалял это на скале. Типа такого:
def findFurthest(current: List[Index])(collection: List[Index]) = collection.map(i => (distance(current)(i), i)).max(order)._2 def sortByDistance(source: List[Index], target:List[Index] = Nil): List[Index] = source match { case Nil => target case more => { val furthest = findFurthest(target)(source) sortByDistance(source.filterNot(furthest==), furthest::target) } } val sorted = sortByDistance(allIndexes).reverse
casual currying
Dec. 1st, 2014 04:54 pmno oop
I wanted this:
But has to write this:
Using it like this:
I wanted this:
def from(location: String) = { def loadTable(name: String, ignoring: String*) { def ignoringColumns(row: String Map String) = row.filterKeys(k => !(ignoring contains k)) val src = Source.fromFile(s"$location/$name.csv").getLines().mkString("\n") val data = parseText(src) map ignoringColumns insertInto(name, data) } }
But has to write this:
case class from(location: String) { self => def loadTable(name: String, ignoring: String*): from = { // actually, the load order is opposite to deletion order update(s"delete from $name") def ignoringColumns(row: String Map String) = row.filterKeys(k => !(ignoring contains k)) val src = Source.fromFile(s"$location/$name.csv").getLines().mkString("\n") val data = parseText(src) map ignoringColumns toList insertInto(name, data) self } }
Using it like this:
from(location). loadTable("users"). loadTable("abusers","historyOfAbuse"). loadTable("WMD","rocks","stones"). loadTable("passwordAndKeys")
reflection, no big deal
Aug. 8th, 2014 05:14 pmI have a mock db, I want to insert a row in a table; the thing is, id were recently converted from
var
to val
(it was an ancient idea of having variable id, something very weird). Now I had to use reflection, so I did.override def insert(o: T): T = { val fields = fieldsOf(o.getClass) val idField = fields("id") idField.set(o, globalID) globalID += 1 update(o) o } } private def fieldsOf(clasz: Class[_]):Map[String, Field] = { def listFields(c: Class[_]): List[Field] = if (c==null) Nil else c.getDeclaredFields .filter (!_.getName.contains("$") ) .toList ++ listFields(c.getSuperclass) val fields = listFields(clasz) fields foreach (_.setAccessible(true)) fields map (f => f.getName -> f) toMap }
one more segmenter
Jul. 31st, 2014 12:27 amGiven a
So this line:
Seq[T]
, and two predicates, p0:T=>Bool
, p1:T=>Bool
, extract segments of the sequence that start with elements satisfying p0
and end with elements satisfying p1
.def extractChunks[T](src:Seq[T], p0:T=>Boolean,p1:T=>Boolean) = { val found:(List[T], List[List[T]]) = ((Nil:List[T], Nil:List[List[T]])/:src) { case ((Nil, out), x) => if (p0(x)) (List(x), out) else (Nil, out) case ((seg, out), x) => if (p1(x)) (Nil, (x::seg)::out) else (x::seg, out) } found._2 map (_.reverse) reverse }
So this line:
println(extractChunks[Char]("abracadabra", 'b'==, 'a'==))
Will print List(List(b, r, a), List(b, r, a))
.
group by relationship
Jul. 23rd, 2014 03:51 pmI have a list, and a binary relationship, and I want to group the list, joining the neighbors that satisfy the relationship. It being equivalence relationship is kind of nice to have, but not necessary. Can be an order actually, so we group monotone sequences. Etc.
(here's version 3, ugly)
This function groups a list into segments where values of a function are the same.
I've been using it for a while.
A test:
Any questions?
(here's version 3, ugly)
def groupByRelationship[T](p: ((T,T) => Boolean)) = { new (List[T] => List[List[T]]) { self => def apply(xs: List[T]): List[List[T]] = xs match { case List() => List() case (x:T) :: _ => val pairs:Iterator[Seq[T]] = xs.sliding(2) val (ps1, ps2) = pairs.span(_.toList match { case a::b::Nil => a==b || p(a, b) case _ => false }) val chain:List[T] = x::(ps1 map (_(1))).toList val tail = ps2.toList collect {case a::b::Nil => b} chain :: self(tail) } } }
This function groups a list into segments where values of a function are the same.
I've been using it for a while.
def groupListBy[T,U](xs: List[T])(f: T => U): List[List[T]] = groupListByRelationship[T](xs)((x,y) => f(x)==f(y))
A test:
val g1 = groupByRelationship[Int](_ < _)(List(1,2,4,2)) g1 must_== List(List(1,2,4), List(2)) val g2 = groupByRelationship[Int](_ > _)(List(1,2,4,2)) g2 must_== List(List(1),List(2), List(4,2))
Any questions?
a style/monads question
May. 30th, 2014 03:05 pmI have this code:
Something does not look nice here.
lazy val eobOpt: Result[EOB] = ... ... def items: Result[Traversable[EOB_item]] = { val listOfParsedItems: Traversable[Result[EOB_item]] = itemsData map { item => { eobOpt flatMap (buildItem(_)(item)) } } Result.traverse(listOfParsedItems).map(_.toList) }
Something does not look nice here.
flatMap
, should not have an alias name, like =>> or something? I can juggle things around, but what I'm looking for is simple beauty, or beautiful simplicity, same thing.using tensor product in scala
May. 30th, 2014 06:35 amI just tried this code:
Why is this important?
See, if I have a class
This is better than having
because in the second case if username is bad, we will never know if prize is bad too; this way we detect only one error. Not so good for fast development. It's like what ancient compilers did.
Questions?
sealed trait Result[+T] { ... def <*>[U](other: Result[U]): Result[(T,U)] ... } case class Good[T](value:T) extends Result[T] { ... def <*>[U](other: Result[U]): Result[(T, U)] = other.flatMap(u => Good((value, u))) ... } case class Bad[T](errors:Traversable...) extends Result[T] { ... def <*>[U](other: Result[U]): Result[(T, U)] = Bad(errors ++ other.errors) ... } scala> val op = Good((1,"one")) op: Good[(Int, String)] = Good((1,one)) scala> for ((i,s) <- op) println(s"i=$i, s=$s") i=1, s=one
Why is this important?
See, if I have a class
Result[T]
, and it is applicative, so Result[T] <*> Result[U]
produces Result[(T,U)]
, I want to use the result, naming individual fields. Like in val username: Result[String] = getUserNameFromTheCloud(userId) val prize: Result[Prize] = rollTheDice val letter:Result[(String, Prize)] = for ((u, p) <- username <*> prize) yield congratulate(u, p) // etc
This is better than having
for(u <- username; p <- prize) yield congratulate(u,p)
because in the second case if username is bad, we will never know if prize is bad too; this way we detect only one error. Not so good for fast development. It's like what ancient compilers did.
Questions?
code critique?
May. 16th, 2014 05:32 pmGuys, I do appreciate your opinions a lot.
What happens here: we upload until we are out of patience with a streak of bad luck, probably meaning the server is dead.
val patience = 10 case class UploadProgress(uploaded: Set[File] = Set.empty, failed: Set[Result[File]] = Set.empty, badLuckStreak: Int = 0) { def errors = Result.traverse(failed) def +(file:File) = { if (badLuckStreak > patience) this else { uploadOneFile(file) match { case Good(file) => UploadProgress(uploaded + file, failed, 0) case bad => UploadProgress(uploaded, failed + bad, badLuckStreak + 1) } } } } def uploadScheduledFiles():UploadProgress = { if (!client.isAlive) UploadProgress(Set.empty, Set(Result.error("Upload server is dead, sorry")), 0) else { (UploadProgress() /: listFilesForUpload)(_ + _) } }
What happens here: we upload until we are out of patience with a streak of bad luck, probably meaning the server is dead.