Pull to refresh
27
0
Андрей Краснобаев @kana-desu

Functional Programming Evangelist

Send message

Тоже задавался этим же вопросом. Пару лет назад покупал себе рокетбук, из которого стиралось все просто водой. По итогу кто-то случайно там что-то обычной ручкой написал, было обидно. Ну и в целом не особо прижилось, потому что буквально через пару месяцев я купил себе ipad pro с пером, который полностью заменил вообще всю бумагу что у меня была.


Но несколько месяцев назад ко мне доехал remarkable второй версии, и уже полностью заменил айпад. Тоже удобный вывод с устройства, неплохо держит заряд (в отличии от айпада, который часто в нужный момент оказывался разряжен), приятные ощущения от письма (в отличии от стекла на айпаде).


Девушке же купил onyx book note. И сравнил с ремаркабл. И вышло, что onyx book note лучше во всем, кроме текстуры экрана (все то же стекло что на айпаде). Хорошо разбирает русский текст например (в ремаркабл распознавания русского нет в принципе).


По поводу кода, f# не знаю, но на хаскеле было бы так:


splitPath :: Text -> Text
splitPath = Text.intercalate "/" . init . Text.splitOn "/"

подозреваю что на f# примерно так же, смог написать только так:


let init xs = Seq.take (Seq.length xs - 1) xs

let splitPath (path: string) = 
  path.Split "/" |> init |> String.concat "/"

printf "%s" (splitPath "C:/users/test/folder")
Тут неясно, что мешает компилятору определить с чем он имеет дело, кортежи явно указываются как кортежи и две палки со стрелочкой рядом с ними выглядят избыточно.

А если функция принимает кортеж? А если функция полиморфна? Невозможно это определять компилятором в общем случае.


оказывается, компилятор не смог определить, что имеет дело со строкой из типа входного объекта.

А как он это поймет, метод Split может быть у чего угодно, тип никак не указан, а каких-нибудь анонимных интерфейсов насколько я знаю в языке нет (чтобы у аргумента был тип "любой тип, который содержит метод Split")
достаточно было просто указать тип аргументу


Абсолютно не понятно, зачем писать так:


let splitPath inputObject = 
  let mutable inputObject : string = inputObject
  ...

когда можно просто так:


let splitPath (inputObject: string) = 
  ...

На схеме, где Васе приходит Insert " Habr" @5, там же ошибка в действиях, которые происходят на Васином клиенте

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


Фриз ничего такого не предоставляет.

ну это совсм не идрис, я намешал разных синтаксисов разных языков в одном языке, это нигде не скомпилируется в таком виде.


По моему нет, мне приходится вот так писать, но я в идрисе не шарю, тутор пролистал год назад, так что моим словам верить нельзя


record Name where
  constructor MkName
  value : String
  p : LT 0 (length value)

mkName : (value : String) -> {auto p : LT 0 (length value)} -> Name
mkName value {p} = MkName value p

name : Name
name = mkName "kana"

Есть такой способ "сэмулировать" зависимые типы как синглтон-типы. Синглтон типы — это типы с одним значением. В данном контексте мы имеем в виду, что если у "исходного" типа будет N значений, то синглтон-типов будет тоже N на каждое значение. Это нужно для того, чтобы на типах полностью сохранить (продублировать) значение.


data Nat = Z | S Nat
-- generate also "kind" Nat (there are no kinds anymore) and two types Z : Nat, S : Nat -> Nat, using DataKinds
data SNat :: Nat -> Type where
  SZ :: SNat Z
  SS :: SNat n -> SNat (S n)

SS (SS (SZ)) :: SNat (S (S Z))

и теперь можно делать примитивные зависимости. Подобный подход реализован у flow в js. По крайней мере так это выглядит. Можно представить систему типов flow как:


  • у нас есть синглтон типы на все значения:
    (true : true);
    (false : false);
    (2 : 2);
    ("hello" : "hello");
    ([1, 2] : [1, 2]);
  • у нас есть юнионы типов (не суммы, а именно юнионы) и апкастинг к юниону от его элементов:
    type bool = true | false;
    ((true : true) : bool);
    ((2 : 2) : 2 | 3) : number);
    // где number = 0.5 | 1 | 2| 3 | ... встроенный
  • есть and-тип, требущий выполнения обеих сингнатур:
    (f : (true => string) & (false => number));
  • и есть даункастинг в виде тайп рефайнмента:

declare function f(x: true): string;
declare function f(x: false): number;
function f(x: boolean): string | number {
  if (x === true) {
    (x: true);
    return 'hello';
  } else {
    (x: false);
    return 42;
  }
}

const x: string = f(true);
const y: number = f(false);
// x: number = f(true) будет ошибка типов

ну так объедините два значения в пару, если очень так хотите.


Математически мы имеем тип


Name = { s : String | 0 < length s }

выражаем его "логически"


Name = exist (s : String). 0 < length s

переводим в типы:


Name = (s : String, p : 0 < length s)

часто это описывают так еще


isName s = 0 < length s
Name = (s : String) * isName s

еще любят такой поинтфри


Sigma (A : Type) (B : A -> Type) = (x : A, B x)
Name = Sigma String isName

еще структуркой можно написать


record Name where
  constructor MkName
  value : String
  proof : 0 < length value

f : Name -> String
f { value } = "Hello " <> value <> "!!!"

print $ f (MkName "kana" _) -- можем вывести пруф автоматически иногда, зависит от компилятора

Или скорее всего нет, опять же, из-за человеческой лени. Работать с вездесущим Maybe неудобно, работать вообще с неправильно спроектированной моделью неудобно.

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

Да лекго все объезжаются даже без особого сбрасывания скорости, это не устройство для тарана и довольно маневренное

https://www.youtube.com/watch?v=S8Q4pl4BYjU


У топовых самокатов скорость до сотни кмч

Когда как. Купил Met Parachute и надеваю, когда собираюсь выехать за город или покататься по лыжным трассам на скоростях выше 40, так-то его нужно бы одевать всегда после скорости в 20кмч, но лень. Но в последнее время заставляю себя чаще.

Погода всегда известна заранее, на всякий случай я всегда вожу с собой легкую складываемую в карман курточку, когда холодно или дождь. Обувь заливало, благо почти всегда езжу в октрытой обуви или с дырками/вентиляцией в такую жару.


Думаю да, во многом ситуация такая же как у велика или другого открытого транспорта. Не понятно, зачем вы спрашиваете, если это очевидно.


Более важный вопрос: колесу самому от дождя ничего не будет, а вот в морозы аккум работает хуже.

В непогоду нормально, ездил под сильным ливнем, главное одеться правильно в непромокаемую одежду. А зимой я сам не пробовал, но достаточно много кто ездит, утепляя аккум и ставя шипованную резину.


Да, очевидно комфорта будет меньше от езды на открытом транспорте в непогоду, чем в закрытом, не думаю, что это можно и нужно оспаривать как-то.

У вас очень устаревшие данные, самые медленные современные самокаты едут 25+, а колеса и подавно быстрее.


Мое колесо развивает скорость до 50, ездил на 43 максимум сам, в среднем еду 35, на прямых дорогах 40, как выше уже сказал. По прямой автобус обогнать тяжело, но он останавливается на каждой остановке и уже через 5 остановок будет отставать на 2. Такси нужно ждать столько времени, сколько хватило бы проехать больше половины пути на колесе.


Прямая трасса не нужна, колесо 18 дюймов, без проблем заезжает на бордюры, скорость конечно нужно сбавлять хотя бы до 20, дороги в моем городе ужасны и это крайне чувствовалось на самокате с колесами в 8 дюймов, но на колесе не чувствуется вообще. Повороты же вообще никак не мешают езде, снизил скорость до тех 20 на секуду, повернул, снова за секунду разогнался до 40.


Я замерял, до работы я заезжаю в лучшем случае за 18 минут, в среднем за 20. И при этом не нужно ждать транспорт. Если я проснусь за 25 минут до того, как мне срочно нужно будет быть на работе, на такси я точно не успею, в отличии от колеса.


Причем все это — не какая-то велодорожка, у нас их нет, это даже может быть не тратуар, а езда по траве, земле и дворам для среза.

Ну серьезно никто же не будет на них ездить на работу

Почему? Именно так и делаю, мне до работы всего 7км, сначала добирался на сяокате, теперь на моноколесе. И половина коллег на велосипеде. После целой жизни езды на велосипеде смотрю на колесо как на нереальный шаг развития, потому что:
а) очевидно быстрее, чем на велосипеде (да что там говорить, быстрее чем на автобусе и даже такси, который ждать минимум минут 10, когда я до работы за 15-20 добираюсь на колесе), средняя моя скорость — 35км/ч;
б) не потею и не устаю, к сожалению нет душа в офисе и это критично.


А как круто ехать по городу и пить чай со своей кружки.


Желаю вам просто сначала попробовать.

Рокстары только и делают, что ставят себе задачи на "слабо". И когда им говорят, что они что-то не смогут, они только рады и делают все, чтобы показать, что они намного круче, чем о них думают, изучат материал и таки сделают. И они рады, и заказчик.


В школе на уроках математики рокстары ведут себя так же, постоянно соревнуясь в том, кто сделает сложнейшее задание быстрее и пытаясь обойти друг друга.

Должен сказать, что рокстару абсолютно не интересно делать свой гугл, его в принципе все эти компании мало заботят. Платят, дают свободу, есть с кем поделиться идеями — вот и хорошо.

На всякий случай добавлю, что у webpack тоже есть tree shaking с ES6 модулями (если используется babel, нужно в конфиге отключить трансформацию импортов/экспортов), да и google closure compiller тоже вроде как умел в такое.

Information

Rating
Does not participate
Location
Витебск, Витебская обл., Беларусь
Date of birth
Registered
Activity