
Alexander
06.08.2018
08:07:58
скорее всего

Alister
06.08.2018
08:08:52
а Haskell programming from first principles?

IC
06.08.2018
08:09:49
полезней не читать, а писать уже

Alister
06.08.2018
08:10:19
так что писать, езод начинать что ли учить?

Google

IC
06.08.2018
08:10:35
то, что тебя реально интересует

Евгений
06.08.2018
08:11:13
Ну он круды пишет для веба

IC
06.08.2018
08:12:15
перед есодом я бы начал с чистого wai, потом scotty. а там дальше либо есод для людей, либо сервант для роботов
либо вебсокеты для SPA

Denis
06.08.2018
08:13:13
servant для роботов :D

Dmitry
06.08.2018
08:42:47
Подскажите, а QuickCheck - это ещё годное решение для генерации юнит-тестов? Или есть что-то более новое?
А то пишут, мол "QuickCheck is the grandfather of property-based testing libraries."
https://begriffs.com/posts/2017-01-14-design-use-quickcheck.html

Yuriy
06.08.2018
08:44:35
это годное решение для property тестов
генерить юниттесты — это странный подход
зачем тебе генерить юниттесты?

Dmitry
06.08.2018
08:46:07
Ну да, правильно. Мне надо property-тесты
Для них появилось что-то лучшее QuickCheck?

Google

Yuriy
06.08.2018
08:46:23
более новое есть, например, hedgehog, он более красивый, но концептуально то же самое
hedgehog разве что более явный, поэтому более понятно, что именно ты тестируешь, с другой стороны, больше кода писать

Index
06.08.2018
08:48:36
Самое дурное изобретение QuickCheck это делать класс Arbitrary, генераторы намного лучше вручную передавать

Yuriy
06.08.2018
08:49:30

Index
06.08.2018
08:49:57
Очень удобно выбирать между орфанами и перетаскиванием тестовой логики в ядро библиотеки

Timofey
06.08.2018
08:50:52
вот да

Index
06.08.2018
08:50:52
К тому же в разных ситуациях полезны разные алгоритмы генерации, не всегда хочется перебирать всё возможное на свете (из-за инвариантов)

Yuriy
06.08.2018
08:52:14

kana
06.08.2018
08:53:01
чем мешают орфаны в тестовых модулях

Index
06.08.2018
08:55:34
Ну да, ведь тесты это последнее место, где нужен предсказуемый instance selection, именно тесты никто не дебагает

Anatolii
06.08.2018
09:03:06
hedgehog если auto запилили бы - было бы круто
https://github.com/hedgehogqa/haskell-hedgehog/issues/135

Yuriy
06.08.2018
09:11:58

A64m
06.08.2018
09:13:54
тем временем в 8.8 первая (видимо?) микрофича
https://github.com/ghc/ghc/commit/4d91cabcd5e3c603997d9876f6d30204a9b029c6
документация к ней - удаление абзаца из старой документации

Yuriy
06.08.2018
09:14:14

A64m
06.08.2018
09:16:39
чтоб были какие-то проблемы с ними - орфаны должны быть выше по графу зависимостей, если они на самом днище - в тестовом подпакете - никаких проблем с орфанами не будет

Index
06.08.2018
09:17:40

Anatolii
06.08.2018
09:20:21

Google

Yuriy
06.08.2018
09:22:54
можно брать старые /= надо писать новые

Anatolii
06.08.2018
09:24:15
ну тоесть то что делает derive Arbitrary

Yuriy
06.08.2018
09:27:59

Anatolii
06.08.2018
09:29:27

A64m
06.08.2018
09:42:12
в sml, кстати, фича 29 не работает как и в старохаскеле
- fun foo (x : 'a) (xs : 'a list) = not x :: xs;
stdIn:1.35-1.46 Error: operator and operand don't agree [UBOUND match]
operator domain: bool
operand: 'a
in expression:
not x
а в f# работает, но он подозревает, что что-то вы не то делаете
> let foo (x : 'a) (xs : 'a list) = not x :: xs;;
let foo (x : 'a) (xs : 'a list) = not x :: xs;;
--------------------------------------^
stdin(4,39): warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'bool'.
val foo : x:bool -> xs:bool list -> bool list

Serghei
06.08.2018
10:03:20
Да, новость про cabal и правда интересена

Artem
06.08.2018
11:35:48
Все привет. Есть ли альтернативы Yesod?

Index
06.08.2018
11:43:00
Spock

Yuriy
06.08.2018
11:51:57
Spock + переизобрести все велосипеды, что в Есоде из коробки
в общем-то Есод в значительной степени модульный, можно отдельные части заменять, если что-то конкретное необходимо улучшить

ParkeT
06.08.2018
12:19:29
Пробую написать Ван Лаарховен_овские линзы в Elm:
https://ellie-app.com/YsS7zmJKvLa1
Без аннотаций типов работают. С - нет. Аннотации закомментированы.
Если раскомментить получаем:
https://ellie-app.com/YsW8DSbjjha1
Function `set` is expecting the 3rd argument to be:
{ a : { b : ∞ } }
But it is:
{ a : { b : number } }

A64m
06.08.2018
12:48:48
понравилось, что диль ретвитнул
"just a reminder that the GHC user's guide has information about language extensions with explanations, code examples, links to literature, and more"
картер шонвальд, оказывается, собирался выдвигаться в рулевой комитет, но что-то не стал

Alexander
06.08.2018
12:59:23
через месяц выдвигается
блин, мне нравится эта штука, но ведь ее не все оценят :/

A64m
06.08.2018
13:01:48
посмотрел твиттер второго нового комитетчика (который не брагилевский). из 6 (ре)твитов (за этот год)
1 - ссылка на совместный доклад с автором ликвид-хаскеля
1 - #AbolishICE
4 - ненависть к илону маску

Dmitry
06.08.2018
13:21:24
А подскажите, почему такой код компилится?
data VType = VA | VB deriving Generic
data VX (ty :: VType) alg a = VX { height :: Int, time :: Int } deriving Generic
....
-- Тесты на Hedgehog + QuickTest:
property_can_serialize :: Property
property_can_serialize = property $ do
vx <- forAll (Gen.arbitrary :: Gen (VX ty TestAlg TestData))
-- ^ вот тут я просто написал `ty`, а оно скомпилилось, почему??
assert $ not $ BS.null (Codec.serialise vx)

Google

Yuriy
06.08.2018
13:22:16

Dmitry
06.08.2018
13:22:18
Я ожидал, что там ошибка будет, ведь ty нигде не описано

Admin
ERROR: S client not available

Yuriy
06.08.2018
13:22:48
подразумевается, что в этом месте forall

Dmitry
06.08.2018
13:22:59
И как понять, что тогда Gen порождает, VX 'VA или VX 'VB?

Yuriy
06.08.2018
13:23:30
тип Gen (VX ty TestAlg TestData) получился полиморфный по ty, то есть независимый от ty

Alexander
06.08.2018
13:24:06

Dmitry
06.08.2018
13:24:34
Ну поля у VX действительно не зависят от ty. Но я ж не могу сделать, к примеру, список VX ty?

Yuriy
06.08.2018
13:25:51

Dmitry
06.08.2018
13:25:57
Хм, попробовал
vxs :: [VX ty TestAlg TestBlock]
vxs = undefined
Компилится
Как так??

Yuriy
06.08.2018
13:26:15

Dmitry
06.08.2018
13:26:49
А, блин. Оно потом проинстанциируется
Не, я не про undefined, а про объявление

Yuriy
06.08.2018
13:29:38
важно, что при работе с конкретным мономорфным значением типа [VX ty TestAlg TestBlock] и значение ty будет конкретным и одинаковым для всех элементов списка

A64m
06.08.2018
13:31:42

Dmitry
06.08.2018
13:32:46
Так а разве компилятору вот в этом месте:
```
vx <- forAll (Gen.arbitrary :: Gen (VX ty TestAlg TestData))
```
не нужно вообще все типы определить?

A64m
06.08.2018
13:36:12
а зачем?

Google


Dmitry
06.08.2018
13:36:34
Так, сейчас немного с другой стороны зайду
Код проверю...
Похоже, дошло. Вот я сделал такое:
class MyShow a where
myshow :: a -> String
instance MyShow (VX ty alg a) where
myshow _ = "ty"
instance MyShow (VX 'VA alg a) where
myshow _ = "VA"
instance MyShow (VX 'VB alg a) where
myshow _ = "VB"
...
prop_can_deserialize :: Property
prop_can_deserialize = property $ do
vxs <- forAll (arbitrary :: VX ty ...)
traceM $ myshow vxs
-- ^ вот тут ошибка, Overlapping instances, что-то подобное я и ожидал.
...
Тогда вопрос другой
А как бы красиво сделать, чтобы не было дублирования кода?
Я вот так вот сделал:
prop_can_serialize :: Property
prop_can_serialize = property $ do
forAll arbitrary >>= \case
VA -> do
vx <- forAll (arbitrary :: Gen VX 'VA ...)
assert $ vx == deserialise $ serialise vx
VB -> do
vx <- forAll (arbitrary :: Gen VX 'VB ...)
assert $ vx == deserialise $ serialise vx
Т.е. получается, два почти одинаковых куска.
Как можно избежать дублирования?
Ну и там теоретически VA/VB могут в разных пропорциях генерироваться...


Yuriy
06.08.2018
13:50:29
вынести
vx <- forAll (arbitrary :: Gen VX 'VA ...)
assert $ vx == deserialise $ serialise vx
в функцию, и из кейсов вызывать её, передавая VA или VB на уровне типов

Dmitry
06.08.2018
13:58:33
Ну VA/VB будет же случайно генерироваться. Есть небольшая вероятность, что одна из веток не будет проверена. Ну ладно, это не важно пока.