
Дмитрий
27.11.2017
07:47:37
В минимальных полностью иммутабельных условиях я бы сделал просто метод drain(), который бы возвращал использованный объект уже в новом статусе
Тем самым сформулировав концепцию исчерпанного ресурса
Но вот с мутабельными данными (и, например, с комонадами) такой финт уже не проходит

Denis
27.11.2017
07:49:21
@kana_sama а что есть аффинные типы в х?
https://z-pattern-matching.github.io/

Google

Дмитрий
27.11.2017
07:51:01
Я такую же фиговину делал, но это не выход
Интересный и реально рабочий вариант — реализовать предикаты, Bounded enum в purescript например
То есть это не выход потому что на самом деле мы не выводим тип и не накладываем ограничений, по смыслу происходящего
Что означает что ето обман чтобы набрать классы

Kelin
27.11.2017
07:54:41
Ты по-другому и не сделаешь по сути
В жсе
Все равно получится обман, чтобы набрать классы

Дмитрий
27.11.2017
07:55:23
Не обязательно
Нужно чтобы тем или иным образом можно было использовать конструкции %checks флоу или is тайпскрипта
Тогда будет доказанный вывод типа, иначе — это всё та же анархия

Kelin
27.11.2017
07:57:09
Типа обернуть тип в функцию проверки?
Там где с Object, Date, etc.

Дмитрий
27.11.2017
08:00:58
Явно доказать, почему именно у тебя получился тот или иной тип

Google

Дмитрий
27.11.2017
08:01:26
Тогда можно отследить каждый шаг доказательства и если что — найти ошибку
flow:
function isObject(x: mixed): boolean %checks {
return typeof x === 'object' && x != null
}
typescript (могу немного путать синтаксис) :
function isObject(x: mixed): x is Object {
return typeof x === 'object' && x != null
}
И так далее по аналогии в более сложных случаях
То есть тут мы можем пройтись пошагово и убедиться, что мы всё учли
В флоу это вообще реализуется через мега-абстрактную конструкцию)
function refine<T, P: $Pred<N»(val: mixed, cb: P): $Refine<T, N, P>
Где $Pred<N> — предикат для вывода типов на основании N аргументов, T — выводимый тип (тот самый %checks), $Refine — семантика для описания того, что мы вывели тип T на основании предиката P для N-ого по счёту аргумента
Оч жоско

Kelin
27.11.2017
08:15:09

Дмитрий
27.11.2017
08:16:54
Ок

Kelin
27.11.2017
08:19:41


Дмитрий
27.11.2017
08:20:34
Потому что им регулярно требуется. Достаточно пару раз попробовать сделать type refinement, как сразу понимаешь что не так)
$Pred<N> — это обобщённый предикат, мы вообще не указываем чем он занимается, только говорим что эта функция принимает столько то аргументов
Что упрощает синтаксис
А так как возвращаемый объект у нас в языке всего один, то требуется указать, какой из аргументов теперь выведен как тип T
И всё, вот уже у тебя получается $Refine как минимально возможная конструкция
type MoreThan<N: number> = number
function isMore(x: number, ref: number): boolean %checks {
return x > ref
}
function refine2<T, P: $Pred<2>>(n: number, ref: number, cb: P): $Refine<T, 1, P> {
if (cb(n, ref)) return n
throw new Error()
}
const refinePos = (n: number): MoreThan<0> => refine2(n, 0, isMore)
После чего получаем вместо number тип безопасного положительного числа

andretshurotshka?❄️кде
27.11.2017
09:29:55

Дмитрий
27.11.2017
09:30:25
Ну как ни странно это есть прямо в доках рамды
В качестве примера к sequence (или traverse, не помню)

andretshurotshka?❄️кде
27.11.2017
09:30:57
Не, без maybe
Чтобы флоу на тип числа ругался если это 0

Дмитрий
27.11.2017
09:31:36
Он не может ругаться на числа, он ргумается на тип

Google

andretshurotshka?❄️кде
27.11.2017
09:31:41
Ну

Дмитрий
27.11.2017
09:33:52
function validDivision(x: number, y: number): boolean %checks {
return y !== 0 && isFinite(y)
}
Чтобы флоу на тип числа ругался если это 0
opaque type Finite: number = number
function refine1<T, P: $Pred<1>>(n: number, cb: P): $Refine<T, 1, P> {
if (cb(x)) return x
throw new Error()
}
function validFinite(x: number): boolean %checks {
return x !== 0 && isFinite(x)
}
const toFinite = (x: number): Finite => refine1(x, validFinite)
const div = (x: number, y: Finite) => x / y
Но без Maybe сам каст Finite, как можно заметить, unsafe, так как включает в себя throw
Не спрашивайте плиз почему у меня ноль не Finite ?


andretshurotshka?❄️кде
27.11.2017
09:47:39
я просто открыл пулл реквест tycho01 в тс
declare function safeDivide<
B extends number,
NotZero = ((v: '1') => 'whatever')({
(v: 0): '0';
(v: number): '1';
}(B))
>(a: number, b: B): number;
// Argument of type '"0"' is not assignable to parameter of type '"1"'
safeDivide(3, 1);
safeDivide(3, 0); // should error
И там он пилит дичб

Дмитрий
27.11.2017
09:50:40
Жесть какая-то
Это вообще тайпчекается или просто проходит один кейс?)

andretshurotshka?❄️кде
27.11.2017
09:50:53
Не тайпчекается раз он закомментил)

Дмитрий
27.11.2017
09:51:03
Во во)
Сходу идея — number из аргумента — никогда не тайпчекнется с таким подходом

Дмитрий
27.11.2017
09:51:38
Потому что будет определен в рантайме

andretshurotshka?❄️кде
27.11.2017
09:53:30
interface BoolToString {
(v: false & true): never;
(v: false): 'false';
(v: true): 'true';
(v: boolean): 'true' | 'false';
}
type strTrue = BoolToString(true);
type strFalse = BoolToString(false);
type strEither = BoolToString(true | false);
type strBool = BoolToString(boolean);
type strAny = BoolToString(any); // fails, want the fallback, but yields 'false'
Ну и там всякая такая дичь
это если число из юзер инпута мб не тайпчекнется

Дмитрий
27.11.2017
09:54:31
Так это всё равно же не поможет
function count(x: number, y: number) {
return safeDivide(x, y)
}
Можешь сказать, должна тут быть ошибка или нет?)

Google

andretshurotshka?❄️кде
27.11.2017
09:56:13
кароч надо впиливать зависимые типы

Дмитрий
27.11.2017
09:56:19
Я причём даже догадываюсь, какой он тут может предложить выход — мол если юзать мой стек до последней запятой то тайпчекнется — но это эгоизм

andretshurotshka?❄️кде
27.11.2017
09:56:35
стек?

Дмитрий
27.11.2017
09:56:56
Ну стек в смысле совокупность всего что он с гканти напилили
Тогда может да, но и то очень спорно

andretshurotshka?❄️кде
27.11.2017
09:57:10
это пулл в тс)
на callable types

Дмитрий
27.11.2017
09:57:22
Ох боже мой

andretshurotshka?❄️кде
27.11.2017
09:57:59
Кстати в флоу можно функцию и без call вызвать

Дмитрий
27.11.2017
09:58:03
С таким подходом его ток как диверсанта засылать, блокировать неугодные фичи

Admin
ERROR: S client not available

andretshurotshka?❄️кде
27.11.2017
09:58:15
И без комментов

Дмитрий
27.11.2017
09:58:23
Как?

Denis
27.11.2017
09:59:10
хотя даже больше рефаймент
ну или можно смоделить через Пеано)

andretshurotshka?❄️кде
27.11.2017
10:00:48
Как?
$PropertyType<$ObjMap<{ Param: A }, F>, 'Param'>

Дмитрий
27.11.2017
10:01:07
Так это тот же вызов

andretshurotshka?❄️кде
27.11.2017
10:01:16
Всм?)

Дмитрий
27.11.2017
10:01:49
Ну какая принципиальная разница, каким образом вызывать F, через одну флоу-директиву или через другую?)

Google

Дмитрий
27.11.2017
10:02:03
Только $Call умеет в несколько аргументов, кстати

andretshurotshka?❄️кде
27.11.2017
10:02:50
$PropertyType<$ObjMap<{ Param: A, Param2: B }, F>, 'Param' | 'Param2'>
А так?)
Не сработает?
Хотя да
Да просто в тс даже через маппед нельзя вызвать функцию)

Denis
27.11.2017
10:09:02
рефайд типы и котлин https://blog.simon-wirtz.de/kotlin-reified-types/
https://github.com/JetBrains/kotlin/blob/master/spec-docs/reified-type-parameters.md
привет РС в котлин))) https://github.com/aedans/katalyst

Kelin
27.11.2017
10:11:57

andretshurotshka?❄️кде
27.11.2017
10:12:22
>JavaScript does not support the full Kotlin reflection API

Дмитрий
27.11.2017
10:13:10
Лол
У них кстати тот же $Refine и вышел, только для конкретного случая

? animufag ?
27.11.2017
10:14:19

Denis
27.11.2017
10:17:51
https://realjenius.com/2017/09/08/kotlin-reify/

andretshurotshka?❄️кде
27.11.2017
10:18:48
о нет, джава проблемы
вообще тс тоже умеет в reified
с декораторами

Дмитрий
27.11.2017
10:20:13
Я про это с самого начала упомянул)
Про is

andretshurotshka?❄️кде
27.11.2017
10:20:24
это refined