Timofey
вот да
Vladislav
К тому же в разных ситуациях полезны разные алгоритмы генерации, не всегда хочется перебирать всё возможное на свете (из-за инвариантов)
кана
чем мешают орфаны в тестовых модулях
Vladislav
Ну да, ведь тесты это последнее место, где нужен предсказуемый instance selection, именно тесты никто не дебагает
Anatolii
hedgehog если auto запилили бы - было бы круто
Anatolii
https://github.com/hedgehogqa/haskell-hedgehog/issues/135
Cheese
hedgehog если auto запилили бы - было бы круто
там можно брать arbitrary из QuickCheck
A64m
тем временем в 8.8 первая (видимо?) микрофича https://github.com/ghc/ghc/commit/4d91cabcd5e3c603997d9876f6d30204a9b029c6 документация к ней - удаление абзаца из старой документации
Cheese
hedgehog если auto запилили бы - было бы круто
https://hackage.haskell.org/package/hedgehog-quickcheck
A64m
чтоб были какие-то проблемы с ними - орфаны должны быть выше по графу зависимостей, если они на самом днище - в тестовом подпакете - никаких проблем с орфанами не будет
Vladislav
так инстан селекшон и будет предсказуемый
orphans + overlappable = адская непредсказуемость
Anatolii
там можно брать arbitrary из QuickCheck
ну там же сироты будут опять
Cheese
ну там же сироты будут опять
почему? если ты их не напишешь, то не будут
Cheese
можно брать старые /= надо писать новые
Anatolii
почему? если ты их не напишешь, то не будут
я наверное не понял что либы делают, мне хочется из любого Generic рекорда получить генератор для Hedgehog
Anatolii
ну тоесть то что делает derive Arbitrary
Cheese
я наверное не понял что либы делают, мне хочется из любого Generic рекорда получить генератор для Hedgehog
например, https://www.stackage.org/haddock/lts-12.5/generic-arbitrary-0.1.0/Test-QuickCheck-Arbitrary-Generic.html#v:genericArbitrary но зависимость от QC здесь как бы лишняя
A64m
в 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
Да, новость про cabal и правда интересена
Artem
Все привет. Есть ли альтернативы Yesod?
Vladislav
Spock
Cheese
Spock + переизобрести все велосипеды, что в Есоде из коробки
Cheese
в общем-то Есод в значительной степени модульный, можно отдельные части заменять, если что-то конкретное необходимо улучшить
parket
Пробую написать Ван Лаарховен_овские линзы в 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
понравилось, что диль ретвитнул "just a reminder that the GHC user's guide has information about language extensions with explanations, code examples, links to literature, and more"
A64m
картер шонвальд, оказывается, собирался выдвигаться в рулевой комитет, но что-то не стал
Alexander
через месяц выдвигается
Alexander
блин, мне нравится эта штука, но ведь ее не все оценят :/
A64m
посмотрел твиттер второго нового комитетчика (который не брагилевский). из 6 (ре)твитов (за этот год) 1 - ссылка на совместный доклад с автором ликвид-хаскеля 1 - #AbolishICE 4 - ненависть к илону маску
Dmitry
А подскажите, почему такой код компилится? 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)
Dmitry
Я ожидал, что там ошибка будет, ведь ty нигде не описано
Cheese
подразумевается, что в этом месте forall
Dmitry
И как понять, что тогда Gen порождает, VX 'VA или VX 'VB?
Cheese
тип Gen (VX ty TestAlg TestData) получился полиморфный по ty, то есть независимый от ty
Alexander
я не понял шутку Ж(((
ну он все обещает через месяц сделать
Dmitry
Ну поля у VX действительно не зависят от ty. Но я ж не могу сделать, к примеру, список VX ty?
Dmitry
Хм, попробовал vxs :: [VX ty TestAlg TestBlock] vxs = undefined Компилится
Dmitry
Как так??
Cheese
Хм, попробовал vxs :: [VX ty TestAlg TestBlock] vxs = undefined Компилится
undefined может быть списком, какой бы ty ты ни подставил
Dmitry
А, блин. Оно потом проинстанциируется
Dmitry
Не, я не про undefined, а про объявление
Cheese
Не, я не про undefined, а про объявление
это корректный полиморфный тип
Cheese
важно, что при работе с конкретным мономорфным значением типа [VX ty TestAlg TestBlock] и значение ty будет конкретным и одинаковым для всех элементов списка
Dmitry
Так а разве компилятору вот в этом месте: ``` vx <- forAll (Gen.arbitrary :: Gen (VX ty TestAlg TestData)) ``` не нужно вообще все типы определить?
A64m
а зачем?
Dmitry
Так, сейчас немного с другой стороны зайду
Dmitry
Код проверю...
Dmitry
Похоже, дошло. Вот я сделал такое: 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, что-то подобное я и ожидал. ...
Dmitry
Тогда вопрос другой
Dmitry
А как бы красиво сделать, чтобы не было дублирования кода? Я вот так вот сделал: 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
Dmitry
Т.е. получается, два почти одинаковых куска.
Dmitry
Как можно избежать дублирования?
Dmitry
Ну и там теоретически VA/VB могут в разных пропорциях генерироваться...
Cheese
вынести vx <- forAll (arbitrary :: Gen VX 'VA ...) assert $ vx == deserialise $ serialise vx в функцию, и из кейсов вызывать её, передавая VA или VB на уровне типов
Dmitry
Ну VA/VB будет же случайно генерироваться. Есть небольшая вероятность, что одна из веток не будет проверена. Ну ладно, это не важно пока.
Dmitry
А как на уровне типов передавать VA/VB ?
Dmitry
Что-то не получается
Cheese
классический способ — Proxy f :: Proxy ty -> m a ... VA -> f (Proxy :: Proxy VA)
Dmitry
А, про Proxy мало знаю. Сейчас попробую...
Cheese
современный способ f :: forall ty. m a ... VA -> f @VA
Dmitry
О, вот так ваще атас
Dmitry
А как это назвается?
Cheese
"современный" требует кучу расширений включить
Dmitry
Чтоб загуглить
Cheese
основная часть — TypeApplications
Cheese
Так уж и кучу
3 минимум
IC
AllowAmbiguous, TypeApplications... RankNTypes?
Cheese
AllowAmbiguous, TypeApplications... RankNTypes?
ScopedTypeVariables обычно, чтобы ty уже внутри использовать