Ilya
Спасибо
Пиши в чат, если не получится. И какая свёртка кстати, линейная или циклическая?
Alexander
new :: (Hashable a, Ord a) => Config -> IO (Cache a b)
new Config{..} = do
ref <- newIORef PSQ.empty
pure $ Cache
{ requestOrInternal = \tm k f -> mdo
mbox <- atomicModifyIORef ref $ swap .
PSQ.alter (\case
Just (p,~v) | p >= tm ^-^ cacheLongestAge
-> (Just v, Just (tm, v))
_ -> (Nothing, Just (tm, Lazy result))) k
result <- maybe (trace "f" $ f k) (evaluate . getLazy) mbox
atomicModifyIORef ref $ swap . PSQ.alterMin (\case
Nothing -> ((), Nothing)
Just (kk,p,v)
| p < tm ^-^ cacheLongestAge -> ((), Nothing)
| otherwise -> ((), Just (kk,p,v))
)
pure result
}
Alexander
так сработало
Leonid 🦇
^-^ - найс
Alexander
но добавление Lazy и getLazy не очевидно
Alexander
из бонусов, что неявный лок на вызове evaluate . getLazy
Alexander
т.е. только 1 тред будет работу работать
Alexander
я очень люблю эту фишку, но я боюсь, что это accidental complexity
Alexander
с другой стороны если не это, то мне бы сложные вещи пришлось бы переизобретать
Aleksei (astynax)
^-^ - найс
оператор "котик спрятался, видно только ушки"
Leonid 🦇
оператор nya
кана
а можно ли в семействах добавлять новые типопеременные?
Leonid 🦇
Aleksei (astynax)
И это тоже. Псто я предложил менее виабушный вариант
кана
f :: HasField "a" r0 r1 String Int
=> HasField "b" r1 r2 Int String
=> Record r0
-> Record r2
вот имею такой код, хочу написать хелпер для композиции HasField, но для этого придется скрыть из внешнего скоупа r1 и добавить в скоуп внутри семейства, это реально?
кана
type family RecordDelta fs r0 rn :: Constraint where
RecordDelta '[] r r = ()
RecordDelta ('(name, a -> b) ': fs) r0 rn =
forall r1. (HasField name r0 r1 a b, RecordDelta fs r1 rn)
типа такого
Alexander
Alexander
Евгений
Обычно сложением называют коммутативную операцию
Alexander
википедия ссылаясь на "Каргаполов М. И., Мерзляков Ю.И. Основы теории групп. — 3-е изд.. — Москва: Наука, 1982. — С. 18. — 288 с. — 11 800 экз." использует аддитивная
Alexander
но вообще это класс из vector-space пакета
Alexander
и я не знаю что и как принято называть там откуда родом автор пакета
Cheese
ещё в Хаскеле иногда нужна просто полурешётка, а иногда отдельно верхняя и нижняя. и эти классы никак друг с другом не связать. печалька
Alexander
в numeric-prelude достаточно большая иерархия
Alexander
но полурешеток вроде нету
Cheese
раздельные есть в lattices
Cheese
простую я сам изобретал
Alexander
фигово, что нельзя простым образом добавить в base
Alexander
т.к. сложность бешено быстро растет
Alexander
сложность программирования
Алексей
Что именно? Более вменяемые классы для чисел?
Alexander
ага
Alexander
ну вообще всю эту алгебру честную бы засунуть
Alexander
у нас только vector-space и numeric-prelude как эксперименты
Алексей
Ну хотя бы выдрать аддитивную группу и кольцо из Num
Alexander
может возможнен промежуточный вариант, достать все честные структуры
Алексей
Ну хотя бы аддитивную группу
Cheese
и fromInteger отделить как синтаксический костыль
Alexander
и в transition period сделать Num зависяшим от себя
Alexander
да-да-да
Alexander
реально бесит
Алексей
Всех — слишком много. Выходит по классу на операцию :( С одной стороны так и надо, с другой — морочно
Alexander
ну т.е. будет промежуточный вариант, хочешь - используешь, не хочешь берёшь Int/Double где все есть
A64m
Alexander
о кметтопакет
саша
Вопрос, а почему я в рамках ду нотации часто вижу pure вместо return? Экономия на символах?
A64m
некоторые считают такой подход более принципиальнм
A64m
return - это реликт со времен, когда Monad и Applicative не были в одной иерархии
Cheese
у меня получилась такая иерархия
class CFoo a where foo :: TFoo
class CFoo a => CFooBar a where foobar :: TFooBar
class CFoo a => CFooBaz a where foobaz :: TFooBaz
fooViaBar :: TFooBar -> TFoo
fooViaBaz :: TFooBaz -> TFoo
data X
instance CFoo X where foo = fooViaBar
instance CFooBar X where foobar = (realImplementation)
data Y
instance CFoo Y where foo = fooViaBaz
instance CFooBaz Y where foobaz = (realImplementation)
чувствую, что-то не так, но не могу понять как правильно. что посоветуете?
Alexander
некоторые считают что return путает людей
Alexander
и.к. это не ретурн из императивных яп
Aleksei (astynax)
"pure - для аппликативных выражений, return - для do-блоков" :)
Cheese
Cheese
Алексей
Нужны классы-синонимы. Тогда развесистые иерархии не страшны и можно дробить тайпкласссы. Что-то вроде
class Functor a => Applicative a = Pointed a, Apply a
class Pointed ...
class Apply ...
Можно объявлять инстансы по отдельности, а можно вместе. instance Applicative даёт инстансы Pointed и Apply, инстансы Pointed и Apply дают Applicative
Cheese
Алексей
Гранулярная иерархия становится нестрашной
Алексей
Cheese
Cheese
Cheese
type Applicative a = (Functor a, Pointed a, Apply a)?
Алексей
Да, плюс сахар для объявления инстансов
Алексей
instance Applicative f where
pure = ...
(<*>) = ...
рассахаривается в
instance Pointed f where
pure = ...
instance Apply f where
(<*>) = ...
Алексей
Это про страдания с классами.
Алексей
Тредов нет
Алексей
всё вперемешку
Alexander
а ещё можно Old.Applicative
Alexander
+ deriving via
Алексей
Просто в этом случае мы автоматически получаем инстансы для Pointed и Apply. Для всех типов, где есть Applicative
Alexander
но с дерайвинг в другую сторону не будет
Алексей
А тут в обе стороны
Алексей
Основная идея тут сделать возможным дробление тайпкласссов
Cheese
если менять язык, то можно создавать автоматические классы из функций. правда, все сразу начнут создавать мультиметоды — беззаконные классы
Cheese
classy (+) :: a -> a -> a
instance (+) :: Int -> Int -> Int where ....
Алексей
Автоматические классы?
Cheese
Алексей
Это уже что-то нездоровое, кмк