Пример с fold в статье. «Пример использования Exit может выглядеть так...». fold как и прочие циклические функции из стандартной библиотеки scala нельзя прервать просто средствами самого Try или \/. Для этих целей у меня используется Exit, который удобно интегрирован с Res.
Пример с if. Скажем у вас есть такая функция, использующая Try:
case class F1(x: Int, y: Int)
case class In(f1: F1, f2: Int)
case class Out(z: Int, f2: Int)
def convF1(x: F1): Try[Int] = ???
def convF2(x: Int): Try[Int] = ???
def fn(x: In): Try[Out] = {
if (x.f1.x < 0 && x.f1.y < 0)
return Failure(new Exception("x < 0 && y < 0"))
for {
z <- convF1(x.f1); if (z > 0)
f2 <- convF2(x.f2)
} yield Out(z, f2)
}
Пример с Res:
case class F1(x: Int, y: Int)
case class In(f1: F1, f2: Int)
case class Out(z: Int, f2: Int)
def convF1(x: F1): Res[Int] = ???
def convF2(x: Int): Res[Int] = ???
def fn(x: In): Res[Out] = for {
_ <- Res(x.f1.x >= 0 || x.f1.y >= 0), "x < 0 && y < 0") //работает как assert; позволяет указать сообщение об ошибке
z <- convF1(x.f1);
_ <- Res(z > 0, "z должен быть больше 0")
f2 <- convF2(x.f2)
} yield Out(z, f2)
Т.е. во-первых мы можем делать больше действий в пределах одного for, во-вторых можем указывать свои сообщения об ошибках.
Try и \/ без помощи со стороны в некоторых ситуациях просто не работают. Ситуация с циклами и if, который должен приводить к выходу из функции. Кроме того там не хватает сервисных функций для облегчения интеграции с кодом, не поддерживающим их. Кроме того порой требуют больше кода при преобразовании значений и не позволяют без допиливания уточнять и заменять сообщения об ошибках. Т.е. идея описанного здесь Res — это доведения до более-менее удобного состояния этих самых Try и \/.
Ещё есть такой human json, как HOCON от typesafe. Там возможностей всяких вообще очень много.
Из основных:
— подстановки (причем более продвинутые, чем в yaml);
— автоматические слияния объектов и файлов;
— чтение переменных окружения, если нужно;
— ну и комментарии конечно.
Правда не знаю, как там с реализацией для языков, отличных от java. github.com/typesafehub/config/
Пересечение совместимых типов или общий базовый тип — это лишь вопрос терминологии в контексте вывода типов. Но в целом я вроде бы понял ситуацию. Спасибо за пояснения.
На счет желаемого результата согласен. В большинстве случаев это выглядит удобно. Однако вопрос в том, почему так происходит. Либо в typescript нет общего базового типа, либо вывод типов останавливается где-то посередине по непонятным правилам. Какой вариант правильный?
Вот как раз формально то и получается, что общего типа нет, т.к. нет к нему приведения. Либо есть какие-то ограничения на приведение типов к базовому, но этот принцип не совсем понятен.
Вот в scala подобное компилируется без проблем, т.к. общий тип Any. Это порой дико раздражает, однако формально тут придраться не к чему. А разве в typescript нет общего для всех типа? Я в коде также наблюдаю «any». Нет ли здесь какой-то логической ошибки?
Ошибся веткой. Ответ на комментарий evgeny_kobzev выше.
Таким образом директор всё же может назначить секрутаршу на роль лид-линка. А та при желании может спустить своё самодурство ниже за счет назначения лид-линков в подкругах. И в итоге может иметь возможность испортить жизнь конкретному сотруднику через цепочку подставных лид-линков и у сотрудников не будет возможности защититься от этого.
Конечно это уже гораздо труднее, чем при классической модели, но возможность остается.
Хотелось бы лучше понять какие рычаги власти есть у тех или иных ролей. Потому что пока складывается ощущение, что никто ни на кого влиять не может. Всё держится на желании сотрудника саморазвиваться и улучшать процесс.
Интересна такая, скорее теоретическая ситуация (хотя прецеденты были).
Скажем в вашу компанию каким-то образом попали люди с неблагородными намерениями, объединенные одной целью. Засланцы конкурента, агенты фсб или представители секты бездельников.
В холократии они имеют возможность объединиться в один круг и составить там большинство. Выбрать из своих тех людей, что общаются с внешними кругами и отвечают за какой-то формальный контроль внутри круга. Таким образом у вас создается некий неэффективный круг, на жизнь которого вы извне почти никак не можете повлиять. Всё что вы можете это устранить роль круга. Однако вам чем-то придется заменить эту роль, а люди останутся теми же и смогут опять объединиться внутри круга. Что с этим можно сделать?
И совсем примитивный пример. Круг выбрал лидера. Лидер видит, что кто-то работает неэффективно. Хочет его уволить. Но тот человек душа компании и договаривается со всеми, чтобы сместить текущего лидера и поставить на его место того, кто не будет напрягать.
Кстати, описанные ситуации процветают в управленческих кругах российских городов.
Но в чем разница с функциональной точки зрения, так сказать. Какая разница, будет ли интерфейс присутствовать в объектах, создаваемых с помощью исходного типа?
Т.е. ваш пример мог быть реализован в Scala как-нибудь так: Dual extends AnyRef with Add with Sub with…
ну и соответственно дальше реализация для Dual всех методов, предоставляемых трейтами Add, Sub и т.д.
Т.е. пока только разная форма одного и того же. А вопрос скорее про функционал. Т.е. что можно сделать с типом Dual в Rust, чего нельзя сделать с ним же в Scala, или наоборот. Или может при каком-то подходе кода меньше надо писать, или ещё что-то, важное с точки зрения потребителя этих технологий.
Пример с if. Скажем у вас есть такая функция, использующая Try:
Пример с Res:
Т.е. во-первых мы можем делать больше действий в пределах одного for, во-вторых можем указывать свои сообщения об ошибках.
Из основных:
— подстановки (причем более продвинутые, чем в yaml);
— автоматические слияния объектов и файлов;
— чтение переменных окружения, если нужно;
— ну и комментарии конечно.
Правда не знаю, как там с реализацией для языков, отличных от java.
github.com/typesafehub/config/
здесь вы явно указываете тип int, поэтому ничего другого туда положить нельзя.
Но в статье говорится, что вот это
тоже не должно работать. Вот пытаюсь понять кто прав и как же на самом деле происходит вывод типов.
Вот в scala подобное компилируется без проблем, т.к. общий тип Any. Это порой дико раздражает, однако формально тут придраться не к чему. А разве в typescript нет общего для всех типа? Я в коде также наблюдаю «any». Нет ли здесь какой-то логической ошибки?
Таким образом директор всё же может назначить секрутаршу на роль лид-линка. А та при желании может спустить своё самодурство ниже за счет назначения лид-линков в подкругах. И в итоге может иметь возможность испортить жизнь конкретному сотруднику через цепочку подставных лид-линков и у сотрудников не будет возможности защититься от этого.
Конечно это уже гораздо труднее, чем при классической модели, но возможность остается.
Интересна такая, скорее теоретическая ситуация (хотя прецеденты были).
Скажем в вашу компанию каким-то образом попали люди с неблагородными намерениями, объединенные одной целью. Засланцы конкурента, агенты фсб или представители секты бездельников.
В холократии они имеют возможность объединиться в один круг и составить там большинство. Выбрать из своих тех людей, что общаются с внешними кругами и отвечают за какой-то формальный контроль внутри круга. Таким образом у вас создается некий неэффективный круг, на жизнь которого вы извне почти никак не можете повлиять. Всё что вы можете это устранить роль круга. Однако вам чем-то придется заменить эту роль, а люди останутся теми же и смогут опять объединиться внутри круга. Что с этим можно сделать?
И совсем примитивный пример. Круг выбрал лидера. Лидер видит, что кто-то работает неэффективно. Хочет его уволить. Но тот человек душа компании и договаривается со всеми, чтобы сместить текущего лидера и поставить на его место того, кто не будет напрягать.
Кстати, описанные ситуации процветают в управленческих кругах российских городов.
Т.е. ваш пример мог быть реализован в Scala как-нибудь так: Dual extends AnyRef with Add with Sub with…
ну и соответственно дальше реализация для Dual всех методов, предоставляемых трейтами Add, Sub и т.д.
Т.е. пока только разная форма одного и того же. А вопрос скорее про функционал. Т.е. что можно сделать с типом Dual в Rust, чего нельзя сделать с ним же в Scala, или наоборот. Или может при каком-то подходе кода меньше надо писать, или ещё что-то, важное с точки зрения потребителя этих технологий.
А можете в двух словах пояснить принципиальное отличие? Я по приведенным примерам никаких отличий кроме синтаксиса не заметил.