Alexander
или и то и другое
Alexander
@jagajaga на самом деле если подробнее расскажете то будет всяко интереснее
Alexander
tweag I/o
Alexander
ну вот людям тут было интересно кто вы, я вроде как в курсе более-менее
Alexander
можете о нас у Дункана спросить, он нас немного знает
Alexander
: )
Влод
кроме суперлаконичного сайта есть что-нибудь?
Влод
общественная дейтельность. открытые либы, выступления, статьи
Влод
о, ну хотя бы на прелюд можно посмотреть
Alexander
вот обращайтесь к нам будут разработчики :D
Нурлан
https://t.me/haskelljob
Нурлан
а что вы в этом чатике не пишете?
Нурлан
там так уныло
Artyom
аутсорс аутсорса? IOHK будут довольны :troll:
Нурлан
давайте использовать по назначению
Alexander
дешевле, чем FPC выйдет, насколько я знаю, и не хуже 😏
Alexander
пинайте через Дункана, он может сказать хорошее слово
Alexander
наверное, во всяком случае год назад бы точно сказал
Misha
а кто знает как сделать такой async ioAction, чтобы ioAction запускался лениво только тогда, когда был вызван wait?
Artyom
unsafeInterleaveIO не работает?
Misha
не пробовал, но это какой-то хардкор сразу
Misha
так, начал писать, чего же мне надо и понял, что оно и не должно было работать
Misha
надо еще думать
Alexander
можно сделать так что действие запустится когда твой s используют: let ~s = unsafePerformIO $ async $ ...
Alexander
тогда как только кто-то зафорсит s
Alexander
то действие запустится
Alexander
unsafeInterleaveIO все же другую семантику по сравнению с async имеет
Alexander
если с wait одного треда они не различимы
Alexander
то уже с wait из разных или ожидании через STM разница будет
Misha
в целом задача вот такая: newtype Pr a = Pr (IO (Async a)) getOrCreateP :: TM.Map k (Pr a) -> k -> (k -> IO a) -> STM (Pr a) getOrCreateP prs k fromIO = TM.lookup k prs >>= \case Nothing -> do let pr = Pr (async (fromIO k)) TM.insert pr k prs return pr Just pr -> return pr то есть идея в том, чтобы по ключу k на каждый запрос создавать ровно один promise, на который мы потом по выходу из транзакции сделаем wait. Но штука в том, что я вижу дофига запущенных fromIO на каждый ключ
Misha
то есть либо я что-то фундаментально не так думаю
Misha
либо фиг знает
Misha
TM - это мап из smt-containers
Misha
получается, с одной стороны понятно, что async (fromIO k) может вызываться на каждый рестарт транзакции и это нормально, но выполняться-то он не должен вообще никак
Misha
в общем, буду трейсом смотреть, что там происходит
Alexander
эм у тебя ж лежит IO действие в контецнере
Alexander
и каждый кто его вызывает создаёт новый тред
Alexander
я с телефона уже не могу скопировать код, но могу сказать идею
Alexander
у меня есть тип: data F = Starting (STM a)| Value a| Stopping (STM ())
Alexander
запись в Мапу регистрирует тебя и ты потом делаешь IO действие и кладешь ответ, другие ждут
Alexander
и.е. Nothing -> Starting -> Value
Alexander
первый тред меняет Nothing на Starting и ему возвращается действие которое он должен выполнить когда создаёт переменную (вызовет async у тебя)
Alexander
другие треды если поищут к - получат срартинг
Alexander
и просто вызовут atomically $ action
Alexander
stopping тут не ыажно
Alexander
ну и про исключения смотреть надо, т.к. тут хитро
Alexander
с другой стороны треды если видят стартинг могут просто retry сделать - этого достаточно будет
Alexander
и.е. ещё раз, есть Map (Maybe (Either () a))
Alexander
a=Async x
Alexander
тред делает lookup >>= \case {Nothing -> write Just (Left ()) return Nothing; Just Left{} -> retry ; Just Right{x} -> return Just x}
Alexander
и maybe (async >>= \x -> atomically update x) return на ответ
Alexander
update = lookup>>= case Nothing-> write Just (Right x); Just{} -> invariantViolation
Alexander
Misha ^^ как-то так, у утра могу по человечески написать
Misha
ага, я примерно так и подумал в итоге, что надо data P a = Empty | Working (IO a), сначала класть Empty а уже после завершения транзакции вызывать async
Misha
правда все усложняется конечно
Misha
эм у тебя ж лежит IO действие в контецнере
тогда еще интереснее, он запускает новый тред, даже если транзакция откатывается что ли? это было бы сильно странно
Alexander
ты не запускаешь тред в транзакции
Alexander
ты кладешь туда действие которое когда выполнится создаст асинк
Alexander
в твоём текущем кода
Misha
тогда он должен быть только один на каждый ключ
Alexander
это действие
Alexander
его можно выполниьь
Alexander
хоть одно оно хоть 5 каждый запуск создаст новый async
Alexander
так я очень спать, через 8-9 часов напишу
Misha
ок, конечно
Artyom
можно ли как-то передать “строковый флаг”? то есть, сейчас можно сделать stack build --flag pkg:foo (по сути, передать boolean), а я хочу что-то другое передать пакету pkg --ghc-options-for-pkg="-DFOO=bar" сработало бы, но stack вроде бы поддерживает только --ghc-options для всего, а мне надо передать только в одну зависимость (и я не хочу перекомпилировать все модули с {-# LANGUAGE CPP #-} всюду)
Alexander
у стека разве нельзя в параметрах сборки где и флаги peer-package указать?
Alexander
per-package
Alexander
@lolepezy https://gist.github.com/qnikst/734094449c8f13ffd7979391c24b8f34
Alexander
под свои нужны затюнить надо, например stm-containers вместо Map
Alexander
там 2 версии, свойства примерно написаны
Alexander
как сделать хорошую (без unsafePerformIO) композабельную (полностью в STM) версию с текущим stm я не знаю сходу
Alexander
фига себе на stackage сколько библиотек в категории stm нарожали..
Alexander
3 или 4 либы для chan split!!!
Alexander
это прекрасно
Alexander
@lolepezy похоже с AdvSTM stm-io-hooks можно зоделать
Alexander
а не, не сработает
Alexander
ну и unsafeIOToSTM с каким-то IORef можно наверное