Timofey
вот да
Vladislav
К тому же в разных ситуациях полезны разные алгоритмы генерации, не всегда хочется перебирать всё возможное на свете (из-за инвариантов)
Cheese
кана
кана
чем мешают орфаны в тестовых модулях
Vladislav
Ну да, ведь тесты это последнее место, где нужен предсказуемый instance selection, именно тесты никто не дебагает
Anatolii
hedgehog если auto запилили бы - было бы круто
Anatolii
https://github.com/hedgehogqa/haskell-hedgehog/issues/135
Cheese
A64m
тем временем в 8.8 первая (видимо?) микрофича
https://github.com/ghc/ghc/commit/4d91cabcd5e3c603997d9876f6d30204a9b029c6
документация к ней - удаление абзаца из старой документации
A64m
A64m
чтоб были какие-то проблемы с ними - орфаны должны быть выше по графу зависимостей, если они на самом днище - в тестовом подпакете - никаких проблем с орфанами не будет
Anatolii
Cheese
можно брать старые /= надо писать новые
Anatolii
ну тоесть то что делает derive Arbitrary
Anatolii
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 - ненависть к илону маску
A64m
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)
Cheese
Dmitry
Я ожидал, что там ошибка будет, ведь ty нигде не описано
Cheese
подразумевается, что в этом месте forall
Dmitry
И как понять, что тогда Gen порождает, VX 'VA или VX 'VB?
Cheese
тип Gen (VX ty TestAlg TestData) получился полиморфный по ty, то есть независимый от ty
Dmitry
Ну поля у VX действительно не зависят от ty. Но я ж не могу сделать, к примеру, список VX ty?
Cheese
Dmitry
Хм, попробовал
vxs :: [VX ty TestAlg TestBlock]
vxs = undefined
Компилится
Dmitry
Как так??
Cheese
Cheese
Dmitry
А, блин. Оно потом проинстанциируется
Dmitry
Не, я не про undefined, а про объявление
Cheese
Cheese
важно, что при работе с конкретным мономорфным значением типа [VX ty TestAlg TestBlock] и значение ty будет конкретным и одинаковым для всех элементов списка
A64m
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
Cheese
вынести
vx <- forAll (arbitrary :: Gen VX 'VA ...)
assert $ vx == deserialise $ serialise vx
в функцию, и из кейсов вызывать её, передавая VA или VB на уровне типов
Cheese
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
Чтоб загуглить
IC
Cheese
основная часть — TypeApplications
Cheese
IC
AllowAmbiguous, TypeApplications... RankNTypes?