
Grigory
16.06.2016
07:42:14
да лямбда взлетела)
и зависимые типы используются очень даже -- гетерогенные списки мега популярны)

Denis
16.06.2016
07:53:13
Очень жду родных копродуктов

Const
16.06.2016
07:56:05
копродукты?..

Google

Const
16.06.2016
07:56:41
/me записал шутку

Denis
16.06.2016
08:09:39
sigh

Alex
16.06.2016
08:25:11
> скажи пример, где hott нужен :)
ну в общем-то там же, где и просто зависимые типы
интенсионалка влечет много бойлерплейта, экстенсионалка неразрешима, в обсервационалке нет фактор-типов

Wystan
16.06.2016
10:57:15
Напереусложняют еще ,что дляопердня без 42 паттернов с зависимыми типами и нельзя будет...

Aleksey
16.06.2016
10:59:37
Кстати, дурацкий вопрос: почему в скале нельзя реализовать HList без макро-костылей?

Alex
16.06.2016
10:59:42
это только показывает что для hlist не нужны завтипы :)

Grigory
16.06.2016
10:59:54
вообще то можно) макросы это не костыли
тайпклассами определяешь тип
по факту только конструткор нужен

Aleksey
16.06.2016
11:00:37
Ну то есть вот на пример я тут накидал
scala
trait HList[+H, +T] {
def :: [A] (h: A): HList[A, this.type] = HList(h, this)
}
case class HNode[+H, +T](head: H, tail: T) extends HList[H, T]
object HNil extends HList[Nothing, Nothing]
object HList {
def apply[H, T](x: H, xs: T) = HNode(x, xs)
}
object :: {
def unapply[H, T](hl: HList[H, T]): Option[(H, T)] = hl match {
case HNode(x, xs) => Some((x, xs))
case HNil => None
}
}
Чего здесь не хватает?

Grigory
16.06.2016
11:00:47
у туплов пробелма есть, ты должен знать арность

Google

Grigory
16.06.2016
11:00:51
нельзя работать с n мерным туплом

Wystan
16.06.2016
11:01:28
Там есть функция nth элемент, она типа н переводит в тип по аксиомам пеано.

Aleksey
16.06.2016
11:01:45
(1 :: "2" :: 3.0 :: HNil) match { case _ :: x :: xs => x } // "2"

Grigory
16.06.2016
11:02:07
да и норм хлист)

Alex
16.06.2016
11:02:47
граждане, path-dependent types это не то же что dependent types :)
хоть и звучит похоже

Grigory
16.06.2016
11:04:35
я бы так определил:
HCons[H, T <: HList](head : H, tail : T) extends HList

Wystan
16.06.2016
11:05:25
Сам не понял что написал. Жалко репла рядом нет:(

Alex
16.06.2016
11:06:02
угу, type operators

Warren
16.06.2016
11:07:01
вот здесь приводится пример почему в Shapeless нужны костыли в виде макросов https://vimeo.com/channels/flatmap2016/165837504#t=2712s

Dmitry
16.06.2016
11:07:32

Warren
16.06.2016
11:07:36
в целом - можно обойтись и без макросов, но для некоторых фич без них никак

Grigory
16.06.2016
11:08:22
классный чувак на ссылке

Alex
16.06.2016
11:08:47
сьпевак?

Grigory
16.06.2016
11:08:52
у него еще была речь, про то как и зачем можно использовать kind projector

Warren
16.06.2016
11:09:01
да

Alex
16.06.2016
11:09:20
у него много речей :)

Grigory
16.06.2016
11:09:31
да)

Warren
16.06.2016
11:09:33
так. оратор от природы!

Google

Wystan
16.06.2016
11:11:53
Эх если бы в двух словах кто говорил как и зачем...

Bulbu
16.06.2016
13:53:38
/me

Юрий
16.06.2016
14:06:33
/me

Daniel
16.06.2016
14:16:01
https://vk.com/video146903_167483690

Alexey
16.06.2016
14:25:48
/me
/me

Alex
16.06.2016
14:27:41
/me
/me

Grigory
16.06.2016
14:28:44
lul

Luger
16.06.2016
14:28:51
эпидемия

Aleksey
16.06.2016
14:29:09
/make_me_happy

Dmitry
16.06.2016
14:32:31
/make

Dmitry
16.06.2016
14:32:34
/me
=(
➜ ~ make me happy
make: *** No rule to make target `me'. Stop.

Wystan
16.06.2016
14:33:39
Iterm?

Dmitry
16.06.2016
14:34:45
iterm, zsh

Aleksey
16.06.2016
14:41:03
Как вы считаете, кошерно писать на скале так:
def foo(read: () => Future[String], write: String => Future[Unit])
(implicit ec: ExecutionContext): Future[Unit] = {
def loop(state: Int): Future[Unit] = {
for {
text <- read()
x = text.toInt
newState = state + x
_ <- write(newState.toString)
_ <- loop(newState)
} yield {
()
}
}
loop(0)
}

Wystan
16.06.2016
14:41:51
Коллбеки вообще не кошерно

Aleksey
16.06.2016
14:42:51
Функции передавать некошерно?

Admin
ERROR: S client not available

Google

Wystan
16.06.2016
14:43:51
Конкретно те, которые фьючер возвращают.

Daniel
16.06.2016
14:43:51
ну а чего нет, первое вообще просто ленивый аргумент

Aleksey
16.06.2016
14:45:01

Wystan
16.06.2016
14:47:28
ReaderWriteState monad-то?
Ой даже не знаю:)

Aleksey
16.06.2016
14:55:00
С одной стороны хочется что бы было чисто. С другой стороны не хочется тащить scalaz/cats. Но даже если притащить, то все равно как-то же надо передавать эффекты, правильно?

Daniel
16.06.2016
14:55:52
больше всего меня здесь пугает
def loop(state: Int): Future[Unit]

Wystan
16.06.2016
15:50:54
Я не знаю конечную цель, но если стоит задача scale, recover from failures, то все трансформации пишешь как чистые функции и оборачиваешь в akka streams. Ну я бы так делал.

Grigory
16.06.2016
16:00:48
да или скалаз стримы)

Pavel
16.06.2016
16:47:12
А как лучше с точки зрения стиля: 5 seconds или 5.seconds? В scala duration

Wystan
16.06.2016
16:51:03


Slavik
16.06.2016
17:35:01
Scala порвала мне шаблон. В Spark 2.0 есть класс:
org.apache.spark.sql.KeyValueGroupedDataset[K, V]
в нем два метода:
def mapGroups[U : Encoder](f: (K, Iterator[V]) => U): Dataset[U]
def reduceGroups(f: (V, V) => V): Dataset[(K, V)]
При этом, первый метод можно вызывать так:
ds.groupByKey(_.country).mapGroups { (a, b) =>
a
}
и так:
ds.groupByKey(_.country).mapGroups { case (a, b) =>
a
}
второй метод так работает:
val t = ds.groupByKey(_.country).reduceGroups { (a, b) =>
a
}
а так вызывает ошибку:
scala> val t = ds.groupByKey(_.country).reduceGroups { case (a, b) =>
| a
| }
<console>:40: error: missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: ?
val t = ds.groupByKey(_.country).reduceGroups { case (a, b) =>
^
в чем между ними разница?
мда... тайна раскрыта. Проблема с overload'ами для Java API:
def mapGroups[U](f: MapGroupsFunction[K, V, U], encoder: Encoder[U]): Dataset[U]
def reduceGroups(f: (V, V) => V): Dataset[(K, V)]
у ф-ции reduceGroups один параметр и он пытается матчить
сорри, overload второго метода:
def reduceGroups(f: ReduceFunction[V]): Dataset[(K, V)]


Aleksey
16.06.2016
17:48:49
Меня тут в соседнем чатике попросили измерить скорость. Получается примерно также как если решать эту задачу аккой. https://gist.github.com/fomkin/ae2b3661e6915aa6092e44708537224f

Pavel
16.06.2016
18:15:12
А это ожидаемо для Play, что вот такие роуты считаются разными и для каждого нужен свой роут?
GET /sub controllers.Controller.index
GET /sub/ controllers.Controller.index
ну тоесть у меня в итоге только так заработало, но я всё же опечален, что надо подобной копипастой заниматься

Vladimir
16.06.2016
18:24:42
хуже того, GET / SomeController.index будет возвращать 404 при запросе без слеша

Google

Pavel
16.06.2016
19:23:37

Vladimir
16.06.2016
19:31:25

Alexandr
16.06.2016
19:59:49
По-хорошему, это задача не Play, а обратного прокси (nginx), который должен редиректить адреса без слэша на адреса со слэшем (или наоборот) с 301-м кодом. Для поисковиков это абсолютно разные url'ы, и любой сеошник скажет, что это плохо, когда один и тот же контент доступен по разным адресам.

Slavik
16.06.2016
20:33:58
@fomkin Я тут для интереса написал то же самое, используя волшебную абстракцию AsyncStream: https://gist.github.com/SlavikBaranov/fcd11a575b564c0179b5d97509a83bf5
в таком варианте получается клевый separation of concerns - отдельно генерация стрима, отдельно стейт машина, отдельно условие выхода, отдельно output

Aleksey
17.06.2016
07:29:55
И как результаты?
В смысле по времени. Сравнимо с чистой аккой на той же задаче?