
Vasily
04.04.2018
12:25:27
Я так понимаю, там дешевле отсортировать как надо при построении вьюшки
Чем что-то ниже городить

Klei
04.04.2018
12:25:35
Ты бегаешь по нему чаще чем его "считывает" вью?

??
04.04.2018
12:25:41
Нужно работать с этим списком, типа удалять, добавлять, после чего сотрированный кидать для обновления вида во вьюху

Google

??
04.04.2018
12:25:50
Ты бегаешь по нему чаще чем его "считывает" вью?
Да. Добавление в список изи, а вот удаление трудновато, как я понял из того, что видел на SOF - делают через матчи совпадения элементов и копирование в новый того, что не совпало с удаляемым (SOF он такой)

Klei
04.04.2018
12:29:15
Если добавление нового чаще происходит около предыдущего, то я бы выбрал зиппер.

??
04.04.2018
12:31:15

Klei
04.04.2018
12:35:24

??
04.04.2018
12:36:44

Klei
04.04.2018
12:37:03
Щас не вспомню, где можно найти. Но структура примитивна и редко используется в чистом виде, обычно сразу адаптируют. Но суть идеи:
type 'a Zipper = Left : 'a list * Right 'a list
module Zipper =
let add item (Zipper (left, right)) =
Zipper(left, item::right)
let tryMoveRight (Zipper (left, right)) =
match right with
| h::t -> Zipper (h::left, t) |> Some
| [] -> None
По необходимости добавляй.

??
04.04.2018
12:42:57
Щас не вспомню, где можно найти. Но структура примитивна и редко используется в чистом виде, обычно сразу адаптируют. Но суть идеи:
type 'a Zipper = Left : 'a list * Right 'a list
module Zipper =
let add item (Zipper (left, right)) =
Zipper(left, item::right)
let tryMoveRight (Zipper (left, right)) =
match right with
| h::t -> Zipper (h::left, t) |> Some
| [] -> None
Не могу понять где тут удаление из левого/правого списка, при добавлении в правую/левую часть.
([], 1, [2; 3; 4])
([1], 2, [3; 4])
([2; 1], 3, [4])
Хотя... h(ead)::t(body), всё понял

Klei
04.04.2018
12:45:55
Не могу понять где тут удаление из левого/правого списка, при добавлении в правую/левую часть.
([], 1, [2; 3; 4])
([1], 2, [3; 4])
([2; 1], 3, [4])
Сам решай, что есть current, расширяй add так, что бы current удовлетворял твоим условиям.

Roman
04.04.2018
13:47:05
https://twitter.com/holytshirt/status/981464641334398976?s=09

??
04.04.2018
14:04:16

Google

Evgeniy
04.04.2018
14:05:45
> obj list

??
04.04.2018
14:06:08

Evgeniy
04.04.2018
14:06:56
@yerumaku Это сознательная потеря типов? :(

??
04.04.2018
14:07:29

Evgeniy
04.04.2018
14:12:35
https://twitter.com/kot_2010/status/981491210656403456

Klei
04.04.2018
14:12:55
Зачем дублировать параметры из конструктора? Они же и так доступны. К тому же не вижу добавления и т.п.

Evgeniy
04.04.2018
14:13:43

??
04.04.2018
14:44:29

Vasily
04.04.2018
15:17:23
Я бы из мемберов вынес в модуль с таким же именем
Реально снимает много проблем
Связанных с привычкой к ооп

??
04.04.2018
15:24:43
Я бы из мемберов вынес в модуль с таким же именем
Как методы расширений? Модуль даст + один класс в метаданные, а если так делать с каждым классом, может быть немного не наглядно, сейчас меньше всего хочется запутаться почему тут не рекорд или не DU (ещё + один класс в метаданные)

Evgeniy
04.04.2018
17:06:47
Привет.


Klei
04.04.2018
19:02:22
Как методы расширений? Модуль даст + один класс в метаданные, а если так делать с каждым классом, может быть немного не наглядно, сейчас меньше всего хочется запутаться почему тут не рекорд или не DU (ещё + один класс в метаданные)
Имелось ввиду, что создается тип и одноименный модуль. Все операции над типом производится посредством функций (если не требуют инкапсуляции). Делается это для того, чтобы не возиться с лямбда адом (List.iter (fun p -> p.Method()) против List.iter MyType.method). К тому же можно создавать одноименные модули в конкретных областях, что позволяет изолировать ограниченно необходимые функции там где надо, а не мозолить ими глаза по всему проекту.
Как правило для иммутабельных типов единственная причина иметь приватные методы, это доступ к скрытым от внешнего наблюдателя данным или дополнительная логика публичного конструктора, которую нет смысла выполнять, если есть гарантия корректности нового объекта. И это не твой случай (судя по тому что видели). // Случай приращение методов к типу на основе функций - лишь хороший тон.
Что касается метаданных и "лишних" типов, то в F# принято плодить чудовищную орду мелких типов. Каждый из которых гарантировал бы корректность строго определенной части данных.
Понятное дело, что сейчас никто не в праве заставлять тебя писать "правильно". Просто будь готов, что по мере приобритения опыта ты начнешь естественным образом склоняться к вышеописанным практикам, и будем лучше, если ты не будешь противодействовать этим тенденциям из-за инерции сознания.
Сорян за лекцию, просто ощущение, что подобные проблемы за последнее время испытывает далеко не первый человек.


Roman
04.04.2018
19:09:47
Имелось ввиду, что создается тип и одноименный модуль. Все операции над типом производится посредством функций (если не требуют инкапсуляции). Делается это для того, чтобы не возиться с лямбда адом (List.iter (fun p -> p.Method()) против List.iter MyType.method). К тому же можно создавать одноименные модули в конкретных областях, что позволяет изолировать ограниченно необходимые функции там где надо, а не мозолить ими глаза по всему проекту.
Как правило для иммутабельных типов единственная причина иметь приватные методы, это доступ к скрытым от внешнего наблюдателя данным или дополнительная логика публичного конструктора, которую нет смысла выполнять, если есть гарантия корректности нового объекта. И это не твой случай (судя по тому что видели). // Случай приращение методов к типу на основе функций - лишь хороший тон.
Что касается метаданных и "лишних" типов, то в F# принято плодить чудовищную орду мелких типов. Каждый из которых гарантировал бы корректность строго определенной части данных.
Понятное дело, что сейчас никто не в праве заставлять тебя писать "правильно". Просто будь готов, что по мере приобритения опыта ты начнешь естественным образом склоняться к вышеописанным практикам, и будем лучше, если ты не будешь противодействовать этим тенденциям из-за инерции сознания.
Напиши статью )


Klei
04.04.2018
19:12:16
Хз. В принципе я своим точно так же мозги промываю, еще полгода и перейду на заученный/выработанные формулировки.

Pavel
04.04.2018
19:22:18

Klei
04.04.2018
19:23:51

Google

Klei
04.04.2018
19:24:48
А при написании тупо композировать проще.

Pavel
04.04.2018
19:25:34
что значит проще?

Klei
04.04.2018
19:28:47
Ты в курсе, что статические методы внутри класса вызываются через его полное имя? Будет у тебя какой нибудь 'static member map ...' и ты будешь его таскать по всему классу в виде 'MyType.map'.
Ясное дело, можно статик лет, с последующим прокидыванием, но зачем?

Evgeniy
04.04.2018
19:29:48

Pavel
04.04.2018
19:31:35

Klei
04.04.2018
19:36:29
А, еще есть проблемы с дженериками, иногда F# требует указывать тип обобщения для статических методов. Бесит невероятно.
Хотя это не про то.

Pavel
04.04.2018
19:40:25
где требует?

Evgeniy
04.04.2018
19:42:49
@deexpp Ты бы лучше свою мысль напрямую донес, без сократовских замашек. :)

Pavel
04.04.2018
19:49:36
но собственно мысль проста. статик мемберы удобнее модуля для типа

Pavel
04.04.2018
19:53:53
Стараюсь их избегать хотя-бы из-за дурацкого синтаксиса)

Vlad
04.04.2018
20:11:40

Vasily
04.04.2018
20:32:36
Ну я попробовал и статические мемберы,и модули, с модулями классы, торчащие наружу,получаются почище

Google

Vasily
04.04.2018
20:33:29
Условно, я объявляю рекорд, и к нему в пару модуль, который содержит create,empty etc
С моей точки зрения, происходит более чистое разделение данных и операций над ними
Концепция статических мемберы все же больше про unit of work, походу, когда класс все о себе знает,и навесить новое поведение довольно проблематично, особенно если контракты в сторонней сборке
Модули лично мне позволяют расширять поведение, не изменяя кода типов данных
Другой вопрос, что модулю нельзя навесить CompiledName по понятным причинам, поэтому из c# код будет выглядеть странновато

Evgeniy
04.04.2018
21:37:51
https://twitter.com/thinkb4coding/status/981621813837991937

Roman
04.04.2018
21:38:36

Evgeniy
04.04.2018
21:51:33

Roman
04.04.2018
21:54:12
Крутотень

Artemy
04.04.2018
22:31:25
https://github.com/Microsoft/visualfsharp/pull/4049

Roman
04.04.2018
22:36:58
SAFE.Template один из самых удобных

Pavel
05.04.2018
02:43:38
перечислю минусы модуля для типа. нельзя: перегрузку функций, утиную типизацию, операторы над типом. сам по себе в этом случае модуль лишняя сущность и в C# выглядит диковато.

Klei
05.04.2018
03:28:31
Кактусом здесь выступают как раз статические методы, а никак не модуль. Из всего перечисленного мне изредка пригождаются разве что операторы. Вообще использование статических методов вначале использования F# является делом привычки, и если уж народ переезжает на модули, значит для этого есть причины.

Friedrich
05.04.2018
04:49:56

Klei
05.04.2018
04:53:53

??
05.04.2018
05:46:02

Klei
05.04.2018
05:51:41
* А зачем столько сопоставлений? Там же достаточно одной проверки current, и двух реакций на нее.
* Тебе точно нужен null? Если хочешь иметь отдельно стоящий current, то может хотя бы на option перейдешь?
* Нет логики поддержания порядка сортировки.

Google

??
05.04.2018
06:06:04

Klei
05.04.2018
06:11:35
Тогда я перестаю понимать, зачем здесь zipper? Он удобен для упорядоченного хранения, редкого упорядоченного и частых неупорядоченных прохождений. Если порядок никак не влияет на внутренюю логику, то есть резон просто хранить list (и по желанию при построении вью пробрасывать упорядоченный список обратно,)

??
05.04.2018
06:18:34

Alex
05.04.2018
06:19:44

Klei
05.04.2018
06:20:03

??
05.04.2018
06:23:19

Vasily
05.04.2018
06:25:18
Удаление, как я понимаю, довольно редкая операция, и в целом ее можно с помощью List.filter сделать
Тем более если элементов немного

??
05.04.2018
06:26:16

Vasily
05.04.2018
06:26:40

??
05.04.2018
06:26:51

Vasily
05.04.2018
06:26:53
И жизнь станет проще
Типа int*data

Klei
05.04.2018
06:27:15