Size: a a a

2021 May 14

MF

Mark Florisson in Haskell
Ok got it, sorry for the newbie questions :)
источник

JS

Jerzy Syrowiecki in Haskell
yes
источник

¯

¯\_(ツ)_/¯ in Haskell
нормальной ли практикой будет засунуть эту функцию в ReaderT?
источник

DB

Danil Berestov in Haskell
Пихай что хочешь, не осудим
источник

JS

Jerzy Syrowiecki in Haskell
да
источник
2021 May 15

OS

Oleksandr Shyshko in Haskell
вопрос про Stack/cabal: как побороть ситуацию, когда модуль обнаруживается в 2 зависимых пакетах?

$ stack build
...
./Allure/GameDefinition/game-src/TieKnot.hs:45:1: error:
   Ambiguous module name ‘Content.PlaceKind’:
     it was found in multiple packages:
     Allure-0.10.2.0 LambdaHack-0.10.2.0
источник

A

Anton in Haskell
ребят, как вкатиться в хаскеллисты? сам являюсь шарпистом без опыта работы
источник

OS

Oleksandr Shyshko in Haskell
можно начать с 2 курсов Москвина:
- https://stepik.org/course/75/promo
- https://stepik.org/course/693/promo
параллельно читать статьи и блоги, начать свой хобби проект.
после Москвина можно продолжить читать книжки:
- Parallel and Concurrent Programming in Haskell
- Thinking with Types (Sandy Maguire)
источник

A

Anton in Haskell
о, у меня куча проектов на шарпе написано, поэтому попробую переписать на хаскелль
спасибо
источник

m

monagatep in Haskell
Подскажите, а как можно отследить зацикливания в программе?

Есть древний (на stack LTS-8.5) проект, он использует Servant. Пытаюсь обновить до 17.9, уже почти удалось, но вот возникла проблема, посылаю POST-запрос, программа начинает потихоньку выжирать всю память и падает.

Запрос:
curl 'http://localhost:3003/api/private/itinerary/77' -H 'Content-Type: application/json' --data-raw '{"plan_id":270031,"country":"belize"}' --verbose

Насколько я понимаю, должно прийти в этот Endpoint:

type UpdateById = Capture "id" ItineraryId :> PostWithValidation Itinerary Itinerary

updateById :: AppSessionServer UpdateById
updateById id Itinerary{..} = do
 liftIO $ putStrLn ("~~~~~~~ updateById ~~~~~~~~~~~~~~~" :: P.String)
 runExceptT $ doDb $ do
     suid <- requireLoggedInUser
     requireAuth (hasCountryRole Reservations itineraryCountry)
     pgUpdate id [ ItineraryTrip_name =. itineraryTrip_name
                 , ItineraryLast_user_id =. Just suid
                 ]
     newRec <- pgGet404 id
     pure newRec

Но вот до putStrLn дело вообще не доходит.

Если послать кривой запрос, напр., --data-raw '{"plan_id":270031}'  (`country обязательно поле) то сервер отвечает ошибкой. Если запустить stack ghci и там сделать JSON.decode "{\"plan_id\":270031,\"country\":\"belize\"} :: Itinerary -- то распарсивает. Поэтому я делаю вывод, что хотя бы парсинг работает корректно.

Но что тогда зависает и выжирает всю память? Как это можно найти? Можно ли как-то получить стектрейсы всех потоков, например? Это бы облегчило дело.

Какая вообще тактика поиска зависаний Servant?
источник

m

monagatep in Haskell
Т.е. я даже не знаю, какие есть промежуточные места в Servant, где можно было бы какие-то логи поставить, чтобы понять, где там сбой
источник

m

monagatep in Haskell
А вот такой эндпоинт отрабатывает:
type GetItineraryById = Capture "id" ItineraryId :> GetJSON (Entity Itinerary)

-- | pgGet just an itinerary
getById :: AppSessionServer GetItineraryById
getById id = do
 liftIO $ putStrLn ("~~~~~~~ getById ~~~~~~~~~~~~~~~" :: P.String)
 rec <- doDb $ pgGet404 id
 requireAuth (hasCountryRole Reservations (itineraryCountry rec))
 pure $ Entity id rec
источник

JS

Jerzy Syrowiecki in Haskell
1. один модуль переименовать
2. один модуль не экспортировать, если не нужен
3. один пакет не депендить, если не нужен
4. PackageImports
источник

JS

Jerzy Syrowiecki in Haskell
traceShowM везде можно
источник

JS

Jerzy Syrowiecki in Haskell
стэктрэйсы включаются ключом RTS -xc в режиме профилирования
источник

¯

¯\_(ツ)_/¯ in Haskell
у меня получилось что-то такое:
class SectorGetter a where
 getSector :: a -> Integer -> Integer -> BL.ByteString

однако, я понял, что если a = ByteString, то всё хорошо, но если a = Handle, то придётся возвращать IO ByteString, что не соответствует сигнатуре. может, тогда не пытаться писать единый интерфейс, а всё-таки написать две реализации (пусть, они и будут почти идентичны)?
источник

JS

Jerzy Syrowiecki in Haskell
да, DRY не закон. можно сначала покопировать, а потом обобщить, если будет нужда
источник

m

monagatep in Haskell
Где именно "везде"?

Последнее, где я могу вставить traceStack, это вот это место:

myPrivateApp :: AppResources -> Vault.Key (S.Session IO Text ByteString) -> Middleware -> Application
myPrivateApp resources sessKey sessMiddleware =
 sessMiddleware $ \req resF -> do
   let sess = fromMaybe (error "Can't find session in vault. Configuration error.") (Vault.lookup sessKey (vault req))
   let resF' = \res ->
         let res' = mapResponseHeaders (\hdrs -> (hCacheControl,"private, no-cache, no-store, must-revalidate"):hdrs) res
         in resF res'
   serve myPrivateAPI (hoistServer myPrivateAPI (runAppSessionCtxNT resources sess) myPrivateServer) req resF'


Дальше управление уходит вглубь Servant.
источник

JS

Jerzy Syrowiecki in Haskell
везде во своём коде
источник

m

monagatep in Haskell
Ну, можно, конечно, взять код Servant и там понавставлять trace-ов... Но неужели это самый простой путь?
источник