
Artemy
29.06.2017
19:37:34
Ну это типа стандартные контролы UI.Next
По сути WebSharper.Forms — надстройка над UI.Next
Или же WebSharper.Piglets для UI.Next

seq
29.06.2017
19:41:18
Artemy я понял в чем моя ошибка была, он мне показывал только один вариант метода, перегрузку с дополнительным параметром ошибки не было..

Google

Artemy
29.06.2017
19:42:32
Кстати, вот статья про WebSharper.Forms:
https://kimsereyblog.blogspot.com.by/2016/03/create-forms-with-websharperforms.html
Этот хорошийчеловек много статей по WebSharper написал.

seq
29.06.2017
19:43:24
Artemy точнее даже так, провтыкал параметр, он мне жаловался что возврщает функцию string -> Form, в общем провтыкал один параметр((

Artemy
29.06.2017
19:43:40
msg?)

seq
29.06.2017
19:44:34
Да, у меня ошибка типа "я возвращаю тебе string -> Form, а мне нужен Form". Ох..))
За ссылочку спасибо)

Artemy
29.06.2017
19:45:01
Сам изначально про msg забыл и такую же ошибку получал.

seq
29.06.2017
19:45:30
Да, где-то на этого чувака натыкался помню, ссылка где-то в Pocket лежит)

Artemy
29.06.2017
19:45:53
Неудивительно. Он чуть ли не единственный, кто про WebSharper пишет.
Особенно из более-менее нового.

Aleksander
29.06.2017
19:46:17

Igor
29.06.2017
19:49:16
Основная проблема была в <> и тут
_ when (XPathSelectElement doc "rss") <> null -> Rss
компилятор точно так же ругается
Lint: `x <> null`; suggestion: Consider using pattern matching, or if you're using F# 4 then `isNull`.
А вот за ative-pattern и синтаксис “метод this args” спасибо (никогда его раньше не юзал)

Google

Aleksander
29.06.2017
19:54:35
а что тогда мешает написать так:
let (|Rss|Atom|) doc =
match doc with
| _ when not <| isNull (XPathSelectElement doc "rss") -> Rss
| _ when not <| isNull (XPathSelectElement doc "atom") <> null -> Atom
| _ -> failwith "unkonwn document type"

Igor
29.06.2017
19:56:16
Да ничего, кроме того что изначально 3 строчки, а тут уже 17

Aleksander
29.06.2017
20:06:19
Можно и компактней, но уже без активных паттернов
let parseDoc' doc =
match doc with
| _ when not <| isNull (XPathSelectElement doc "rss") -> parseRss doc
| _ when not <| isNull (XPathSelectElement doc "atom") -> parseAtom doc
| _ -> failwith "unkonwn document type"
4 строчки

Ivan
29.06.2017
20:06:49
isNull x |> not - почему не так?l

Aleksander
29.06.2017
20:07:18
исключительно дело вкуса :)
not последним мне не нравится, легко пропустить

Ivan
29.06.2017
20:09:53
Я об начальном варианте:
if doc.XPathSelectElement("//channel/item") |> isNull |> not then parseRss doc
else if doc.XPathSelectElement("atom:feed//atom:entry", ns) |> isNull |> not then parseAtom doc
else []

Igor
29.06.2017
20:14:06
Да, тоже вариант.
В общем спасибо всем, дальше я как нибудь сам выберу

Aleksander
29.06.2017
20:59:39
Хм, а на сиквенсах даже интереснее получается:
let tryParse xPath parseFun doc = if (not <| isNull (XPathSelectElement doc xPath)) then Some(parseFun doc) else None
let parseDoc''' doc =
[
tryParse "rss" parseRss doc;
tryParse "atom" parseAtom doc;
Some("default value")
] |> Seq.pick id

Evgeniy
30.06.2017
06:22:10
JetBrains Rider EAP 24 is out: performance optimization, F# Interactive, Unity fixes, better web.config support
https://blog.jetbrains.com/dotnet/2017/06/29/rider-eap-24-includes-performance-fixes-f-interactive/

Pawel
30.06.2017
07:22:29
о, репл сделали

Ed
30.06.2017
07:29:23
Какую бы такую иммутабельную структуру данных использовать для FIFO очереди под Fable?

Klei
30.06.2017
07:46:07

Ed
30.06.2017
07:48:01
двух списков? мне пока пришло в голову сделать цепочку:
type Item<'a> = { item: 'a; rest: Queue<'a> }
and Queue<'a> = | Empty | Item of Item<'a>

Klei
30.06.2017
07:52:10

Vasily
30.06.2017
07:52:28
Есть же Nessos.Streams
Вполне под данную задачу ложатся

Ed
30.06.2017
07:53:02
под Fable пойдёт?

Google

Klei
30.06.2017
07:59:20

Ed
30.06.2017
08:01:46
а, тоже прикольно

Pawel
30.06.2017
13:04:48
OMG, какой изврат...

Ed
30.06.2017
13:05:13
ща гляну
нету
есть только вот это
System.Collections.Generic.List
Array
System.Collections.Generic.HashSet
Set
System.Collections.Generic.Dictionary
Map
а то я уже реализовал модуль с очередью из двух списков

Klei
30.06.2017
13:09:20
OMG, какой изврат...
Кроме того, что он не имеет нормальной обертки (что для учебного курса совершенно нормально) в чем извращенность?

Ed
30.06.2017
13:10:10
module Fable.EdIlyin.Queue
type 'a queue = | Queue of 'a list * 'a list
let empty = Queue ([], [])
let singleton item = Queue ([item], [])
let push (Queue (l, r)) item = Queue (l, item :: r)
let ofList list = Queue (list, [])
let rec peek (Queue (l, r)) =
match l with
| [] ->
match r with
| [] -> None
| _ -> List.rev r |> ofList |> peek
| h::_ -> Some h
let rec pull (Queue (l, r)) =
match l with
| [] ->
match r with
| [] -> None
| _ -> List.rev r |> ofList |> pull
| h::t -> Some (h, t)
let length (Queue (l, r)) = List.length l + List.length r

Roman
30.06.2017
13:10:12

Ed
30.06.2017
13:12:02

Pawel
30.06.2017
13:15:27

Roman
30.06.2017
13:19:27

Pawel
30.06.2017
13:20:32

Klei
30.06.2017
13:24:04

Pawel
30.06.2017
13:28:51
она ни фига не оптимизирована, потому что List.rev. Такое прокатывает только в hello world.
Иммутабельность ради иммутабельности - это и есть изврат.

Google

Klei
30.06.2017
13:34:52

Ed
30.06.2017
13:45:54
Возможно с иммутабельностью я погорячился. Просто хочеться чего-то в функциональном стиле

Pawel
30.06.2017
13:49:08
== Каждый элемент подпадает под List.rev лишь однажды
ну то есть колекция N раз реверсируется. Классная оптимизация ,ага.
== Тем более мне неизвестна причина по которой требуется иммутабельность
Вообще то апи определяет выбор структур данных, а не на оборот. Иногда требуется иммутабельное апи. Из этого ни разу не следует, что структуры данных обязаны быть иммутабельными. Если конечно обойтись без фанатизма.

Klei
30.06.2017
14:01:15

Pawel
30.06.2017
14:51:20


Klei
30.06.2017
15:20:56
== Какова сложность List.rev на списке в 1 элемент?
то есть данная очередь по перформансу прекрасно подходит для хелуворда, где количество элементов в колекции мизерное и выбор структуры данных не имеет ни какого значения, с чем ни кто и не спорит ?
== убер машину для Queue на массивах и деревьях
человек возьмёт array и будет счастлив, поскольку вся функциональность queue в нём есть и ничего велосипедить не надо ?
== Давайте устроем плач по копированию массива при переполнении.
Нет, давайте лучше притягивать за уши функциональшину туда, где она на фиг не впёрлась!
> то есть данная очередь по перформансу прекрасно подходит для хелуворда, где количество элементов в колекции мизерное и выбор структуры данных не имеет ни какого значения, с чем ни кто и не спорит ?
Я пояснил, что ты неправильно понимаешь момент выполнения List.rev.
> человек возьмёт array и будет счастлив, поскольку вся функциональность queue в нём есть и ничего велосипедить не надо ?
> Нет, давайте лучше притягивать за уши функциональшину туда, где она на фиг не впёрлась!
Я имею ввиду сложность написания иммутабельной структуры данных на мутабельных коллекциях внутри. Если нужна иммутабельность, то игнорирование списков - есть жутчайший велосипед.
А то что в случае изменяемых коллекций можно взять готовое, никто не оспаривает.


Ed
30.06.2017
16:08:18

Pawel
30.06.2017
16:09:09
а иммутабл стейт - это что в данном случае?


Ed
30.06.2017
16:13:59
это рекорд
он рекурсивно передаётся
в MailboxProcessor'е
module Fable.EdIlyin.Throttle
open System
type Model =
{ quantity: int
millisecond: int
queue: int Queue.queue
}
and Msg<'a> =
| Die
| Fetch of (unit -> 'a) * AsyncReplyChannel<'a>
let execute func (channel: AsyncReplyChannel<_>) model =
do func () |> channel.Reply
{ model with queue = Queue.push model.queue DateTime.Now.Millisecond }
|> Debug.log "executed"
let fetch model func channel =
async {
do! match Queue.pull model.queue, Queue.length model.queue with
| None, _ -> async.Return ()
| _, l when l < model.quantity -> async.Return ()
| _, l when l >= model.quantity -> async.Return ()
| Some (was, tail), _ ->
DateTime.Now.Millisecond
- was
|> (-) model.millisecond
|> Async.Sleep
return execute func channel model
}
let body model (agent: MailboxProcessor<_>) =
let rec loop state =
async {
let! msg = agent.Receive ()
return!
match msg with
| Die -> async.Return ()
| Fetch (func, channel) ->
async {
let! newModel = fetch state func channel
return! loop newModel
}
}
loop model
let agent quantity millisecond =
body
{ quantity = quantity
millisecond = millisecond
queue = Queue.empty
}
|> MailboxProcessor.Start


Pawel
30.06.2017
16:17:19
в MailboxProcessor'е
то есть ни каких особых причин делать очередь иммутабельной нет. можно с таким же успехом хранить стейт в массиве и апдейтить его в цикле while

Evgeniy
30.06.2017
16:17:30
@edvail Большие куски кода, пожалуйста, выкладывайте в пастебин или gists.

Ed
30.06.2017
16:18:05

Evgeniy
30.06.2017
16:19:01

Ed
30.06.2017
16:19:03

Pawel
30.06.2017
16:19:21
не очкуй!

Ed
30.06.2017
16:19:49
а я очкую

Google

Ed
30.06.2017
16:19:51
:)


Pawel
30.06.2017
16:24:11
> то есть данная очередь по перформансу прекрасно подходит для хелуворда, где количество элементов в колекции мизерное и выбор структуры данных не имеет ни какого значения, с чем ни кто и не спорит ?
Я пояснил, что ты неправильно понимаешь момент выполнения List.rev.
> человек возьмёт array и будет счастлив, поскольку вся функциональность queue в нём есть и ничего велосипедить не надо ?
> Нет, давайте лучше притягивать за уши функциональшину туда, где она на фиг не впёрлась!
Я имею ввиду сложность написания иммутабельной структуры данных на мутабельных коллекциях внутри. Если нужна иммутабельность, то игнорирование списков - есть жутчайший велосипед.
А то что в случае изменяемых коллекций можно взять готовое, никто не оспаривает.
== Я пояснил, что ты неправильно понимаешь момент выполнения List.rev
всё зависит от сценария использования
== сложность написания иммутабельной структуры данных на мутабельных коллекциях внутри
а зачем это нужно? Если апи иммутабельное, то какая половая разница на каких структурах данных оно реализовано?
== А то что в случае изменяемых коллекций можно взять готовое, никто не оспаривает.
вопрос в том зачем вообще брать сложное, не стандартное и не эффективное при наличии простого, стандартного и эффективного


Vasily
30.06.2017
16:26:32
Все никак не соберусь Окасаки прочитать про функциональные типы данных и алгоритмы.Мне кажется, проблема с очередью там должна решаться

Pawel
30.06.2017
16:29:02
Проблема с очередью в ФП не решаеттся от слова вообще. ФП - это про деревья. Массивы, очереди и сортировка - это императивщина
точнее - графы
более или менее хорош вектор в виде дерева хэшей в clojure, но в F# к сожалению ничего подобного нет

Andrew
30.06.2017
16:45:51
Есть ли в F# готовая такая функция: (fun x y -> x, y) ?

Ed
30.06.2017
16:57:36
что именно пугает?
Я себя как программиста боюсь. Я опять чтонить сделаю так, что меняя один объект будут меняться ещё куча других. У меня мозг маленький - я всё упомнить не могу и не хочу :) А потом это всё траблшутить для меня убийственно. Или когда синхронизация данных в две стороны - это тоже меня вгоняло в депрессию. Хочу что бы данные шли только в одном направлении и что бы компилятор меня контроллировал

Evgeniy
30.06.2017
16:58:08
@angmarr https://github.com/fable-compiler/fable-react_native-demo/pull/20#issuecomment-312308422

Ed
30.06.2017
17:00:12
ладно, раз уж я пишу под Fable то для очереди буду использовать Emit javascript
var queue = [];
queue.push(2); // queue is now [2]
queue.push(5); // queue is now [2, 5]
var i = queue.shift(); // queue is now [5]


Klei
30.06.2017
18:08:25
== Я пояснил, что ты неправильно понимаешь момент выполнения List.rev
всё зависит от сценария использования
== сложность написания иммутабельной структуры данных на мутабельных коллекциях внутри
а зачем это нужно? Если апи иммутабельное, то какая половая разница на каких структурах данных оно реализовано?
== А то что в случае изменяемых коллекций можно взять готовое, никто не оспаривает.
вопрос в том зачем вообще брать сложное, не стандартное и не эффективное при наличии простого, стандартного и эффективного
Последний раз пишу.
> всё зависит от сценария использования
List.rev суммарно обработает максимум N элементов. В List.map например гарантированно List.rev вызовится на всех N.
> а зачем это нужно? Если апи иммутабельное, то какая половая разница на каких структурах данных оно реализовано?
Я так понимаю, что опыта реализации сего чуда у автора этих строк не было. Это банально больно, если не иметь соответствующей квалификации.
> вопрос в том зачем вообще брать сложное, не стандартное и не эффективное при наличии простого, стандартного и эффективного
Такое можно было сказать, лишь напрочь потеряв весь контекст диалога.
> Проблема с очередью в ФП не решаеттся от слова вообще.
Очередь (как и стек) в ФП решаются прекрасно.
Вообще, мне не понятно, реализацию очереди двумя способами: через кольцо и два стека проходят на 1-2 курсе профильных специальностей (это если в школе не было программирования). Реализация на двух списках является клоном 2-ух стекового варианта. Я что-то не припомню, чтобы мои преподы с пеной у рта доказывали, что стеки гавно, массив форевер. На экзе дрючили оба варианта.


Roman
30.06.2017
18:35:01

Pawel
30.06.2017
19:29:46

Evgeniy
30.06.2017
19:32:33