Aleksei (astynax)
data X
= A
| B
тут то зачем? здесь всё выравнивается нормально :)
Aleksei (astynax)
К слову, type level lists в коде у нас сильно меньше, чем всего остального. Зато единообразие присутствует везде.
кана
даже дата сверху выглядит приятнее, чем '[
Denis
вот для этого стиль и нужен, потому что от обсуждения кому что приятнее - профессиональное пригорание
Aleksei (astynax)
Я пригорал, помнится
Aleksei (astynax)
А теперь у меня в 99% случаев стайлчекер сразу доволен :)
кана
единый стиль нужен, но это же нужно еще выбрать, какой стиль нужен в качестве единого
Denis
это долго все выбирали, в итоге какими-то моментами поступились(вроде тех же тайп-левел листов) для простоты правил
Denis
миллион корнеркейсов все равно никто держать в голове не может
Denis
вообще это реально неприятная роль - гайдом по стилю заниматься
Denis
Все кругом недовольны, кругом корнеркейсы и потом все выглядит по меньшей мере так себе. Зато в команде боли субъективно меньше(тут зависит от того у какого процента горит от разметки, это случается не у всех).
Denis
взаимные компромиссы, взаимоуважение - лучше так, чем в расстановке букв постоянно красоту искать
Oleg
we must overcome our type inference training and learn to see types as pushing requirements inwards, as well as pulling guarantees out
Oleg
© conor mcbride
A64m
ну вот когда вся макбрайдовщина будет нормально имплементирована и работать для чего-то кроме индексированного длиной списка - тогда и поговорим
A64m
а пока превозмогать привычку к выводу типов рановато
Oleg
Да я просто не сдержался. Два месяца терпел, чтобы вбросить, когда скаловый инференс поносить будут
A64m
в скале нету вывода же
Oleg
A64m
грустно
Ю ли я? 🤔
> Scala has a built-in type inference mechanism which allows the programmer to omit certain type annotations.
A64m
реконструкция есть, а вывода нет
Oleg
* that barely works even in one direction
Евгений
A64m
нет
Oleg
летс терминоложи баттл бегинс
Евгений
нет
В чем разница тогда
?
A64m
вывод - это дамас-милнер и модификации, а реконструкция - все остальное
Ю ли я? 🤔
"потому что я так сказал"
A64m
потому что между этими двумя случаями есть существенная, практически значимая разница
A64m
на самом деле, если смотреть в этом ключе то и "дамас-милнер и модификации" можно разделить на три практически различающиеся вещи
Anonymous
Вот в C# и джаве хороший тон начать с интерфейсов и тестов, а потом переходить к имплементации.
Т.е., типы важны потребителям кода (напр., мученикам из поддержки). Даже если компилятор обойдётся.
A64m
но аннотировать даже в хаскеле принято больше, чем только это
A64m
топлевельные определения, которые частью интерфейса не являются тоже аннотируются
Cheese
если кому-то интересная моя борьба с красотой, 5 переменными и линзами, то я переписал State+Bookkeeper+OverloadedLabels на ST. получилось почти столь же компактно, да ещё и работать стало на порядок быстрее
A64m
и хуже чем пять парамеров?
Cheese
A64m
и хуже чем рекорд и леннартовский пм для него
Kirill
а что такое "леннартовский пм"?
A64m
RecordWildCards
A64m
не принципиально
Anatolii
через genericToJSON все таки сделал нужный мне инстанс ToJSON
Anatolii
теперь захотел вынести код вотдельную функцию
Anatolii
f x = case genericToJSON defaultOptions x of
Object o -> o
_ -> error "toObject: value isn't an Object"
Anatolii
и хочу же написать сигнатуру чтобы компилятор не ругался
Anatolii
library/CompletionReport/Report.hs:61:1: warning: [-Wmissing-exported-signatures]
Top-level binding with no type signature:
f :: (aeson-1.2.4.0:Data.Aeson.Types.ToJSON.GToJSON
Value Zero (Rep a),
Generic a) =>
a -> Object
Anatolii
добавляю сигнатуру
f :: (GToJSON Value Zero (Rep a), Generic a) => a -> Object
Anatolii
и получаю
library/CompletionReport/Report.hs:61:7: error:
• Expecting one fewer arguments to ‘GToJSON Value Zero’
Expected kind ‘(* -> *) -> Constraint’,
but ‘GToJSON Value Zero’ has kind ‘Constraint’
• In the type signature:
f :: (GToJSON Value Zero (Rep a), Generic a) => a -> Object
|
61 | f :: (GToJSON Value Zero (Rep a), Generic a) => a -> Object
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
library/CompletionReport/Report.hs:61:21: error:
• Expected kind ‘* -> *’, but ‘Zero’ has kind ‘*’
• In the second argument of ‘GToJSON’, namely ‘Zero’
In the type signature:
f :: (GToJSON Value Zero (Rep a), Generic a) => a -> Object
|
61 | f :: (GToJSON Value Zero (Rep a), Generic a) => a -> Object
| ^^^^
Cheese
там разные GToJSON
Cheese
есть GToJSON, а есть GToJSON
Cheese
короче, убери Value
Cheese
type GToJSON = ToJSON.GToJSON Value
Anatolii
спасиб
Anatolii
я просто оч удивлялся что у genericToJSON такая же сигнатура:)
Кабачок
Как называется ситуация, когда есть пачка тайпклассов и не совсем понятно как их комбить, typeclass hell?
Alexander
не уверен что этой ситуации давали специальное имя
Кабачок
Пусть будет без имени, есть какие-нибудь гайды как с этим бороться?
Alexander
лучше вопрос задай, что не понятно
Alexander
это как вопрос, есть библиотеки и непонятно как их композить
Alexander
ну что на это ответить?
Кабачок
Просто иногда хочется написать что-то вроде Foo <=> Bar и реализовав один класс, получать инстанс второго
Cheese
ты просто не должен этого хотеть. это не связано с комбинацией классов
Cheese
если они друг из друга следуют, то это должен быть один класс
Кабачок
Есть отдельные сво-ва типа рефлексивности\симметричности\тразитивности и не понятно как их комбить в разнообразные отношения
Кабачок
Equivalence это Reflexive+Symmetric+Transitive, но когда каждое сво-во в отдельном интерфейсе нельзя просто объявить какое-нибудь отношение эквивалентностью, сначала надо написать другие инстансы
Кабачок
А если сгруппировать все свойства в составные интерфейсы тоже будет плохо, они бывают нужны по одиночке
Cheese
сделай 3 класса для R, S, T, и четвёртый, который от них зависит
A64m
Кабачок
A64m
в идрисе нет тайпклассов
проблема решена
Ilya
всё-таки классы включают в себя тайпклассы как подмножество, так что есть
Евгений
Cheese
Кабачок
Да, я, конечно не самый умный человек.
Необходимо:
class (R, S, T) => E where
Достаточно:
instance (R, S, T) => E where
Вот и эквивалентность.