@haskellru

Страница 1228 из 1551
Ilya
28.05.2018
18:20:36
сейчас попробую натянуть

Ilya
28.05.2018
18:39:12
немного неправильно, в этом случае придется везде заворачивать по месту использования

я вообще пытаюсь сделать что бы у меня была монада пораждающая значения типа T

Google
Ilya
28.05.2018
18:39:47
и возможны всякие другие типы, которые тоже можно привести к типу Gen T

например локальная или глобальная переменная

собственно для этого и есть тайплкасс продьюсер

а заассайненый тайп OutType это типа оутпут продьюсера, но проблема что я не могу его задефайнить для непосредственно абстрактной монады с констрейнтом GenFunMonad, потому что тайпчекер отбрасывает этот контекст и спроведливо жалуется что инстанс для монадического кейса свлишком общий

Ilya
28.05.2018
18:43:35
пользователи библиотеки будут страдать

дырявая абстракция получается

у меня так-то есть реализация без GenFunMonad где конкретная монада лежит и там всё это прекрасно работает

но проблема в том, что в этом случае не получится нормально заворачивать конкретную монаду в другие трансформеры

пользователи библиотеки будут страдать
я правда пока единственный пользователь библиотеки ?

попробовал извратиться через фандепы, но уткнулся в то же самое место

Denis
28.05.2018
18:47:45
так, дальше код надо смотреть

я пальцем в небо попытался понять что хотите

Google
Ilya
28.05.2018
18:49:58
сценарий использования приблизительно такой

https://github.com/SPY/haskell-wasm/blob/master/src/Language/Wasm/Builder.hs#L807-L825

kana
28.05.2018
18:50:09
круто бы примеры упрощать до абстрактных, а то тут сходу кучу ненужной информации, вместо понимания проблемы я читаю именя типов чтобы понять что это

Ilya
28.05.2018
18:50:30
да, я пытался вначале ?

попробую абстракнее сформулировать

kana
28.05.2018
18:51:53
ну как я понял

Denis
28.05.2018
18:52:03
где-то было у меня такое недавно

kana
28.05.2018
18:52:04
нужен инстанс семейств от констрейтов инстансов

Denis
28.05.2018
18:55:33
@lonokhov У тебя вроде вот с сервантом такая же шляпа была как человек спрашивает. Не могу вспомнить точное решение, но смутно помню, что там нужно чтобы правая часть была разная в разных ассоциированных TF. Не напомнишь?

https://gist.github.com/SPY/ff745898629800f967949cd14ead1ed5

Ilya у @lonokhov было такое недавно, можно как-то переписать чтобы все работало

Dmitry
28.05.2018
18:58:08
А мое предложение не устраивает?

Denis
28.05.2018
18:59:08
если мне память не изменяет, то правые части в TF разные должны быть

сходу я бы предложить попробовать с Tagged вместо Proxy, чтобы их дифференцировать, но возможно я фигню говорю

Leonid
28.05.2018
18:59:55
Тут в обоих случаях Proxy t выходит. У меня выходило разное

Dmitry
28.05.2018
19:00:23
"правые части в TF разные" - я не понимаю, что ты имеешь в виду. Можно пример, чего нельзя?

Denis
28.05.2018
19:00:34
впрочем, если работает уже, то почему бы и нет?

Dmitry
28.05.2018
19:01:02
насчет "работает" - не факт ;-)

Google
kana
28.05.2018
19:01:05
про правые части - это уже какая-то инъективность

Ilya
28.05.2018
19:03:27
А мое предложение не устраивает?
я проверял фандепы. сейчас попробую ваш вариант.

дочь периодически заставлять отвлекаться от хаскеля ?

kana
28.05.2018
19:03:55
фандепы в данной ситуации будут иметь те же проблемы, что и семейства

Ilya
28.05.2018
19:04:37
фандепы в данной ситуации будут иметь те же проблемы, что и семейства
да, я предполагал что так будет(эквивалентны же), но попробовать стоило

сходу я бы предложить попробовать с Tagged вместо Proxy, чтобы их дифференцировать, но возможно я фигню говорю
я не могу разные правы части, мне как раз надо из разных типов один и тот же тип распаковывать по факту

kana
28.05.2018
19:07:30
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeFamilies #-} data Wrapper a = Wrapper class Class a where type ClassType a instance Class (Wrapper t) where type ClassType (Wrapper t) = t instance Monad m => Class (m (Wrapper t)) where type ClassType (m (Wrapper t)) = t вот уменьшенный пример

Denis
28.05.2018
19:08:19
это же Proxy data Wrapper a = Wrapper

kana
28.05.2018
19:08:30
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} data Wrapper a = Wrapper class Class a b | a -> b instance Class (Wrapper t) t instance Monad m => Class (m (Wrapper t)) t и вот он на фандепах

это же Proxy data Wrapper a = Wrapper
да, я убрал лишний импорт, чтобы еще и инстанс монады у прокси убрать лишний

{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} data Wrapper1 a = Wrapper1 data Wrapper2 a = Wrapper2 class Class a b | a -> b instance Class (Wrapper1 t) t instance Monad m => Class (m (Wrapper2 t)) t взял разные обертки чтобы ближе к оригиналу

Ilya
28.05.2018
19:10:59
что бы совсем ближе надо из враппера1 доставать враппер2

и из m (Wrapper1 t) тоже доставать Wrapper2 t

в этом случае как раз GHC резонно начинается ругаться что инстанс для монады полностью оверлапит инстанс для узкого кейса

потому что у Wrapper1 и (Monad m => m) одинаковые кайнды, как и у внутренних t и (Proxy t)

Denis
28.05.2018
19:14:09
чего-то я выше недопонял задачу и нагнал люто

дополнительный параметр как Дмитрий предложил должен помочь

Ilya
28.05.2018
20:06:56
похоже что работает, сейчас попробую расскоментировать и подправить основной кодбейз и посмотрим не вылезут ли какие-то краевые кейсы при интеграции с другими хаками

Google
Ilya
28.05.2018
20:29:12
вот компилирующийся сжатый экзампл https://gist.github.com/SPY/dc5e70d1bb4de813446c1dd3391b61ae#file-overlapedmulti-hs

вроде разобрался почему он работает(сначала не очевидно было)

Dmitry
28.05.2018
20:33:39
TF IsLoc можно не делать на последних GHC. Использовать (==) import Data.Type.Equality ...... ProducerB (Loc == m) m (m a))

Ilya
28.05.2018
20:35:02
последние это от 8.4?

Dmitry
28.05.2018
20:35:40
8.2 точно работает

Ilya
28.05.2018
20:36:30
ага, но у меня там энивей не 2 инстанса, а 3. Так что придется ввести вспомогательный енум

но в целом работает

Dmitry спасибо

Dmitry
28.05.2018
20:37:26
не нравится ... m (m a) ... как-то на ... m a ... хорошо бы параметры переделать

Ilya
28.05.2018
20:39:11
ну оно только для одного инстанса так криво

для других весьма логично

типа Loc t является продьюсером в монаде m

без этого указания потом гхц погрязнет в амбигуити

Dmitry нет, я всё-таки не до конца догоняю почему оно работает. Потому что IsLoc иньективна и на этом GHC успокаивается?

Dmitry
28.05.2018
21:28:34
хм..., а мне непонятно, что непонятно?

IsLoc, конечно, не инъективна. Почти всегда False дает. Инъективность не при чем

Ilya
28.05.2018
21:33:56
в итоге после интеграции в модуль по месту использования валятся ошибки вида /haskell-wasm/src/Language/Wasm/Builder.hs:264:24: error: • Couldn't match type ‘OutTypeHelp (GetProdType (m34 (Proxy 'F32))) (m34 (Proxy 'F32))’ with ‘OutTypeHelp (GetProdType (m32 (Proxy 'F32))) (m32 (Proxy 'F32))’ arising from a use of ‘sub’

я не уверен, что получится из этого вытянуть изолированный пример, но если кому-нибудь не лень позвать стэк для сборки, то могу закоммитить в веточку нерабочий код

Dmitry
28.05.2018
21:35:07
Была проблема, что Loc t и m (Proxy x) перекрывались. Так как в случае Loc (Proxy t) неясно какой инстанс использовать. Мы сказали, что, если Loc, то нужен инстанс для Loc, а не для m. (Это я телепатически догадался, а GHC не смог). Это мы явно передаем в первом параметре. Важно, что это не в констрейнте, а в нормальном параметре-типе.

А почему в одном месте m34?

Google
Dmitry
28.05.2018
21:36:00
т.е. в двух

почему они должны матчиться?

Если должны, напиши в сигнатуре констрейнт - в той функции, в которой вызываешь. Типа OutTypeHelp a ~ OutTypeHelp b

Ilya
28.05.2018
21:42:10
я покоментировал там лишнее что бы свести проблему к чему-то менее контекстнозависимому

есть например вот такая ошибка: haskell-wasm/src/Language/Wasm/Builder.hs:875:19: error: • Couldn't match type ‘OutType (Glob 'I32)’ with ‘OutType (Loc 'I32)’ arising from a use of ‘add’ NB: ‘OutType’ is a type function, and may not be injective

add :: (GenFunMonad m, Producer m a, Producer m b, OutType a ~ OutType b) => a -> b -> m (OutType a)

и вот само место вызова if' i32 ((heapNext `add` alignedSize) `lt_u` heapEnd)

OutTypeHelp a ~ OutTypeHelp b не так-то просто добавить, он уже 2 аргумента требует

Dmitry
28.05.2018
21:44:37
А чему реально OutType (Glob 'I32) и второй равны?

Ilya
28.05.2018
21:44:50
потому что оба Proxy 'I32

если интересно больше контекста - https://github.com/SPY/haskell-wasm/blob/refactoring/builder-monad/src/Language/Wasm/Builder.hs#L875

Dmitry
28.05.2018
21:46:47
Точно? Замени вызовы на undefined, загрузи ghci, сделай kind! OutType (Glob 'I32)

фух, может завтра гляну как-нибудь...

Ilya
28.05.2018
21:54:39
да, всё равно большое спасибо, у меня как минимум есть направление куда ковырять теперь

btw, λ> :kind! OutType (Glob 'I32) OutType (Glob 'I32) :: * = OutType (Glob 'I32)

он почему-то не раскрывает эту тайпфункцию

Dmitry
29.05.2018
05:10:39
Посмотрел код. Я бы убрал ProducerType и лишний инстанс. Loc и Glob, похоже, одинаковые. Можно передавать Bool. import Data.Type.Bool .... m == Loc || m == Glob ...

Ilya
29.05.2018
05:58:31
Посмотрел код. Я бы убрал ProducerType и лишний инстанс. Loc и Glob, похоже, одинаковые. Можно передавать Bool. import Data.Type.Bool .... m == Loc || m == Glob ...
Но это не решит кейса если один параметр глоб или локал, а второй экспрешен монадический

Я не очень понимаю почему гхц не может раскрыть OutType

Страница 1228 из 1551