
alexknvl
22.09.2018
09:16:56


Denis
22.09.2018
09:16:58

alexknvl
22.09.2018
09:17:22

kana
22.09.2018
09:17:45
хитрый constraint в Fix
да, вот в нем и неудобство, слишком много старнный констрейтов придется требовать для обобщенного кода, который будет такое использовать

Google

kana
22.09.2018
09:18:07
и там такое как выше не опишешь уже)

Yuriy
22.09.2018
09:18:31

Denis
22.09.2018
09:19:36
а по поводу категориальности, есть еще такой пакет
https://github.com/sjoerdvisscher/data-category

kana
22.09.2018
09:20:13
то есть вот тут у нас инстанс над Fix, а ограничивать нужно аргументы для Fix


alexknvl
22.09.2018
09:23:58
есть ещё https://github.com/mikeizbicki/subhask
по-хорошему надо как-то так:
class Category (cat :: k -> k -> *) where
type Obj cat (a :: k) :: Constraint
id :: Obj cat a => cat a a
(.) :: (Obj cat a, Obj cat b, Obj cat c) => cat b c -> cat a b -> cat a c
instance Category (->) where
type Obj (->) a = ()
id = P.id
(.) = (P..)
newtype f ~> g = Nat { runNat :: forall x. f x -> g x }
instance Category (~>) where
type Obj (~>) a = ()
id = Nat id
(.) f g = Nat (runNat f . runNat g)
class (Category cat1, Category cat2, forall a. Obj cat1 a => Obj cat2 (f a)) =>
Functor (cat1 :: k1 -> k1 -> *) (cat2 :: k2 -> k2 -> *) (f :: k1 -> k2) where
map :: (Obj cat1 a, Obj cat1 b) => (a `cat1` b) -> (f a `cat2` f b)
но GHC у меня слишком старый для QuantifiedContexts
это тебе и даст C Fix f => C f (Fix f)
можно для Nat попросить type Obj (~>) f = Functor f

kana
22.09.2018
09:55:54
хм, ну да, это все таки ограниченная категория объектов, а не ограничения на функтор

Google


kana
22.09.2018
09:56:12
я пытался ставить ограничения на конструтор ~>, но они конечно не вытягивались в функторе
{-# LANGUAGE RankNTypes
, TypeOperators
, MultiParamTypeClasses
, TypeInType
, TypeFamilies
, UndecidableInstances
, StandaloneDeriving
, FlexibleContexts
, ConstraintKinds
#-}
import Prelude hiding (Functor, map)
import Data.Kind
import Data.Function (fix)
class Category (cat :: k -> k -> Type) where
type Object cat (a :: k) :: Constraint
cat_id :: Object cat a => a `cat` a
cat_compose :: (Object cat a, Object cat b, Object cat c)
=> b `cat` c -> a `cat` b -> a `cat` c
instance Category (->) where
type Object (->) a = ()
cat_id = id
cat_compose = (.)
instance Category (~>) where
type Object (~>) f = Functor (->) (->) f
cat_id = Nat id
cat_compose f g = Nat (runNat f . runNat g)
class (Category cat1, Category cat2) => Functor cat1 cat2 (f :: obj1 -> obj2) where
map :: (Object cat1 a, Object cat1 b, Object cat2 (f a), Object cat2 (f b))
=> (a `cat1` b) -> (f a `cat2` f b)
instance Functor (->) (->) Maybe where
map = fmap
instance Functor (->) (->) [] where
map = fmap
instance Functor (~>) (->) Fix where
map eta = fix (\f -> Fix . runNat eta . map f . unFix)
newtype (f :: Type -> Type) ~> (g :: Type -> Type) = Nat { runNat :: forall x. f x -> g x }
newtype Fix f = Fix { unFix :: f (Fix f) }
deriving instance Show (f (Fix f)) => Show (Fix f)
type HaskFunctor = Functor (->) (->)
hoist :: (HaskFunctor f, HaskFunctor g) => (forall x. f x -> g x) -> Fix f -> Fix g
hoist f = map (Nat f)
toList :: Maybe a -> [a]
toList (Just x) = [x]
toList Nothing = []
x :: Fix Maybe
x = Fix (Just (Fix (Just (Fix Nothing))))
y, z :: Fix []
y = hoist toList x
z = map (Nat toList) x
намного лучше


Denis
22.09.2018
10:03:38
{-# LANGUAGE RankNTypes
, TypeOperators
, MultiParamTypeClasses
, TypeInType
, TypeFamilies
, UndecidableInstances
, StandaloneDeriving
, FlexibleContexts
, ConstraintKinds
#-}
import Prelude hiding (Functor, map)
import Data.Kind
import Data.Function (fix)
class Category (cat :: k -> k -> Type) where
type Object cat (a :: k) :: Constraint
cat_id :: Object cat a => a `cat` a
cat_compose :: (Object cat a, Object cat b, Object cat c)
=> b `cat` c -> a `cat` b -> a `cat` c
instance Category (->) where
type Object (->) a = ()
cat_id = id
cat_compose = (.)
instance Category (~>) where
type Object (~>) f = Functor (->) (->) f
cat_id = Nat id
cat_compose f g = Nat (runNat f . runNat g)
class (Category cat1, Category cat2) => Functor cat1 cat2 (f :: obj1 -> obj2) where
map :: (Object cat1 a, Object cat1 b, Object cat2 (f a), Object cat2 (f b))
=> (a `cat1` b) -> (f a `cat2` f b)
instance Functor (->) (->) Maybe where
map = fmap
instance Functor (->) (->) [] where
map = fmap
instance Functor (~>) (->) Fix where
map eta = fix (\f -> Fix . runNat eta . map f . unFix)
newtype (f :: Type -> Type) ~> (g :: Type -> Type) = Nat { runNat :: forall x. f x -> g x }
newtype Fix f = Fix { unFix :: f (Fix f) }
deriving instance Show (f (Fix f)) => Show (Fix f)
type HaskFunctor = Functor (->) (->)
hoist :: (HaskFunctor f, HaskFunctor g) => (forall x. f x -> g x) -> Fix f -> Fix g
hoist f = map (Nat f)
toList :: Maybe a -> [a]
toList (Just x) = [x]
toList Nothing = []
x :: Fix Maybe
x = Fix (Just (Fix (Just (Fix Nothing))))
y, z :: Fix []
y = hoist toList x
z = map (Nat toList) x
такс, чем это отличается от предидущего?


kana
22.09.2018
10:04:15
нет констрейтов в Functor
они вынесены в более правильное место - в категорию
(~>) - категория конкретно эндофункторов в Hask, а не всех типоконструкторов, из-за этого больше не нужны констрейты в функторе

alexknvl
22.09.2018
10:07:02
я ща экспериментирую с
data Dict (c :: Constraint) where
Dict :: c => Dict c
class (Category cat1, Category cat2) =>
Functor (cat1 :: k1 -> k1 -> *) (cat2 :: k2 -> k2 -> *) (f :: k1 -> k2)
where
obj :: forall a. Obj cat1 a => Dict (Obj cat2 (f a))
map :: (Obj cat1 a, Obj cat1 b) => (a `cat1` b) -> (f a `cat2` f b)

Denis
22.09.2018
10:07:06

kana
22.09.2018
10:07:24

Denis
22.09.2018
10:07:50

alexknvl
22.09.2018
10:08:02
у меня GHC старый

Denis
22.09.2018
10:09:45

alexknvl
22.09.2018
10:10:20
и может быть категорию всех категорий используя Dict

kana
22.09.2018
10:10:26

alexknvl
22.09.2018
10:11:55
да, а можно "The category with categories as objects and functors as arrows." ?
class (Category cat1, Category cat2) =>
Functor (cat1 :: k1 -> k1 -> *) (cat2 :: k2 -> k2 -> *) (f :: k1 -> k2)
where
obj :: forall a. Obj cat1 a => Dict (Obj cat2 (f a))
map :: (Obj cat1 a, Obj cat1 b) => (a `cat1` b) -> (f a `cat2` f b)
instance Functor (->) (->) Maybe where
obj = Dict
map = fmap
instance Functor (->) (->) [] where
obj = Dict
map = fmap
newtype Fix f = Fix { unFix :: f (Fix f) }
deriving instance Show (f (Fix f)) => Show (Fix f)
instance Functor (~>) (->) Fix where
obj = Dict
map eta = fix (\f -> Fix . runNat eta . map f . unFix)

Denis
22.09.2018
10:15:50
@kana_sama ты смотрел Коналовское решение?
https://github.com/conal/concat

alexknvl
22.09.2018
10:16:20
нет ещё

Google

Denis
22.09.2018
10:16:28

alexknvl
22.09.2018
10:17:43
он ща пригодится, попробую категорию категорий написать
всё сложно, надо думать
data CatT (cat1 :: k1 -> k1 -> *) (cat2 :: k2 -> k2 -> *) =
forall (f :: k1 -> k2). Functor cat1 cat2 f => CatT (Proxy f)

Denis
22.09.2018
11:19:45
https://twitter.com/dshevchenko_biz/status/1043459549389352960
Простите за оффтоп, друзья, но я знаю, что здесь много Вимеров...

Ilya
22.09.2018
11:51:30
@ulysses4ever ты про ICFP спрашивал? я вот приехал

Artem
22.09.2018
12:33:33

Ilya
22.09.2018
12:46:29
пиши, как приедешь

timCF
22.09.2018
14:30:28
привет
а никто не знает есть ли какая-нибудь простая в использовании библиотека для поддержки multiline strings с интерполяцией?

IC
22.09.2018
14:37:03
https://hackage.haskell.org/package/interpolate ?

timCF
22.09.2018
14:39:53
спасибо!

Dmitry
22.09.2018
16:22:20
привет
а никто не знает есть ли какая-нибудь простая в использовании библиотека для поддержки multiline strings с интерполяцией?
Смотря, что подразумевается под интерполяцией. Если самая простая для мультистрочных строк, где можно вставлять текстовые переменные, то лучше neat-interpolation:
* http://hackage.haskell.org/package/neat-interpolation
У interpolate, как я вижу, в зависимостях haskell-src-meta, а это значит, что зависимости будут билдиться полчаса, а если на виртуалке с 2Гб памяти, так и вовсе может не сбилдиться. Я бы порекомендовал избегать библиотек с очень тяжёлыми зависимостями, если нет острой необходимости.

timCF
22.09.2018
17:47:33
спасибо, NeatInterpolation - то что нужно

M
22.09.2018
18:28:38
Подскажите какую-нибудь (хорошую) статью/пост про перформанс серванта, как делать и как не делать. Здесь выше у кого-то проект с ним не собирался из-за того, что в память не влезал.

Anton
22.09.2018
18:37:55
Совет простой, не особо мудри с тайплевел фичами, я сам на грабли наступил тогда
По умолчанию сервант хорошо работает, памяти хватит
Я тогда на тайплевел вычислял символьные тэги для доступов авторизации для каждого эндпойнта
Ещё к выжиранию памяти может привести использование vinyl в body запросов
Не думаю, что в эти грабли можно попасть, не зная уже многих других не type level грабель

A64m
22.09.2018
18:40:19
да и вывод инстансов аесона через дженерики

Google

A64m
22.09.2018
18:40:27
если рекорды большие

Anton
22.09.2018
18:41:54
Меня через ghcjs вывод аесон инстансов на TH бесит, компилит модуль с 200 инстансами минут 10
но на дженериках наверное бы в рантайме боль была

A64m
22.09.2018
18:45:07
да они вроде не тормозные

Anton
22.09.2018
18:45:39
Помню на uniplate поверх Generic были большие лаги
А TH нормально справился

Admin
ERROR: S client not available

A64m
22.09.2018
18:47:58
юниплейт-то тормозной

Anton
22.09.2018
18:49:35
Вместе с Generic это было очень заметно

Pineapple
22.09.2018
18:51:24
А можно cabal new-build воспретить пытаться что-то притащить по сети?
Можно. --offline

Alexander
22.09.2018
21:18:34
а у варпа есть возможность сказкать forkWarpProcess
чтобы в случае graceful shutdown этот процесс бы тоже ожидался?

alexknvl
23.09.2018
06:41:42
https://alexknvl.com/posts/counting-type-inhabitants.html

Oleg
23.09.2018
08:10:21
https://alexknvl.com/posts/counting-type-inhabitants.html
We’ve encountered a problem proving that from . to = id
Это следует из натуральности f
Лемма Йонеды ставит в эквивалентность не весь ∀ x. (a -> x) -> f x, а его натуральный сабсет.
Для натуральной f верно что для любой g
f. fmap g == fmap g. f

Denis
23.09.2018
08:13:38
есть просто такая ката
https://www.codewars.com/kata/yoneda-lemma/haskell
и там как раз про инхабитантов тоже есть

Oleg
23.09.2018
08:21:37
Ну как бы и получается, что счёт для полиморфных типов не совсем верен, т.к. основан на натуральности

alexknvl
23.09.2018
08:21:47

Oleg
23.09.2018
08:22:42

Google

Oleg
23.09.2018
08:23:20
Для утверждения о множествах безотносительно хаскеля это тоже верно

alexknvl
23.09.2018
08:23:25
следует из fmap id = id
и из free theorems

Oleg
23.09.2018
08:23:49

alexknvl
23.09.2018
08:24:35
ок, давай по порядку

Oleg
23.09.2018
08:24:47
Давай

alexknvl
23.09.2018
08:24:50
> Это следует из натуральности f
что конкретно имеется в виду под натуральностью f?

Oleg
23.09.2018
08:25:29
forall a. f a -> g a более широкое множество, чем множество естественных трансформаций из f в g

alexknvl
23.09.2018
08:26:12
это не полиморфная функция
это type constructor
ну т.е. f : Type -> Type, только если в этом смысле
естественные трансформации = natural transformation?

Oleg
23.09.2018
08:27:00

alexknvl
23.09.2018
08:27:06
ааа

Oleg
23.09.2018
08:28:14
Это доказуемо, когда f - не любая полиморфная функция, а удовлетворяющая условию натуральности, которое я написал