Size: a a a

2021 June 01

OS

Oleksandr Shyshko in Haskell
вопрос по TypeFamilies: как починить ошибку NB: ‘M’ is a non-injective type family при вызове type family? https://gist.github.com/oshyshko/92c1687de65d26d79c310f67ef79963d
источник

MK

Maxim Koltsov in Haskell
ну ведь там прямо в ошибке сказано что делать
источник

OS

Oleksandr Shyshko in Haskell
хм, я не вижу там никаких рекомендаций от компилятора
источник

YS

Yan Shkurinskiy in Haskell
--       To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
--       When checking the class method:
--         runDb :: forall db a. Db db => M db a -> IO a
--       In the class declaration for ‘Db’
--    |
-- 12 |     runDb :: (M db) a -> IO
источник

YS

Yan Shkurinskiy in Haskell
^
источник

OS

Oleksandr Shyshko in Haskell
добавление AllowAmbiguousTypes не меняет ошибку, если вы об этом
источник

OS

Oleksandr Shyshko in Haskell
(обновлю gist во избежание непоняток)
источник

YS

Yan Shkurinskiy in Haskell
main :: IO ()
main = do
   db <- mkStmDb
   id1 <- runDb @StmDb $ nextId db
попробуйте
источник

YS

Yan Shkurinskiy in Haskell
хотя вроде должно и без этого работать
источник

OS

Oleksandr Shyshko in Haskell
с "id1 <- runDb @StmDb $ nextId db" работает. Но теряется полиморфизм и смысл заводить type family. Я обновил gist, чтобы сделать это более наглядным https://gist.github.com/oshyshko/92c1687de65d26d79c310f67ef79963d есть идеи, как уговорить его срастись?
источник

YS

Yan Shkurinskiy in Haskell
источник

YS

Yan Shkurinskiy in Haskell
Как я понял, при вызове runDb не ясно, какой инстанс брать
источник

YS

Yan Shkurinskiy in Haskell
зная db восстановить  M db мы не можем
источник

YS

Yan Shkurinskiy in Haskell
т.к. не инъективно, как говорилось выше
источник

OS

Oleksandr Shyshko in Haskell
благодарю за разъяснение. Я ожидал, что компилятор сможет вывести StmDb через вызов mkStmDb. Как тогда можно прагматично решить эту проблему используя type families (если это возможно)? Хочется иметь 1 интфейс и несколько реализаций (stm, SQL etc.)
источник

YS

Yan Shkurinskiy in Haskell
я обычно всегда пишу с тайп аппликейшенами
источник

OS

Oleksandr Shyshko in Haskell
а если хочется замокать БД в тестах?
источник

YS

Yan Shkurinskiy in Haskell
runDb @Mock или runDb @App
источник

YS

Yan Shkurinskiy in Haskell
мокать же надо какую-то функцию, которая как раз неоднозначна
источник

YS

Yan Shkurinskiy in Haskell
и при её запуске указать тайп параметр
источник