169 похожих чатов

Почему haskell не может вывести MonadState s m из MonadState

s (ExceptT a m) при том что instance MonadState s (ExceptT a m) вроде требует MonadState s m. Это связанно с Overlappable instances? Можно ли это как-то устранить (пусть не для самого MonadState, а для какой-нибудь своей обёртки над ним)?
Could not deduce (S.MonadState s m)
arising from the superclasses of an instance declaration
from the context: (Monad m, S.MonadState s (ExceptT a m))
bound by a quantified context

3 ответов

29 просмотров

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

Например потому тайпклассы в коре компилируются в явную работу со словарями, и если что-то можно вывести в тайпчекере это /должно/ означать это что-то можно вытащить из соответствующего словаря, e.g. class Monad m => MonadState s m | m -> s where get :: m s put :: s -> m () ... instance MonadState s m => MonadState s (ExceptT e m) where get = liftExceptT get put = liftExceptT . put ... =>> data MonadState s m = MonadState { superclass :: Monad m , get :: m s , put :: s -> m () } monadStateExceptT :: MonadState s m -> MonadState s (ExceptT e m) monadStateExceptT MonadState{superclass, get, put} = MonadState { superclass = monadExceptT superclass , get = liftExceptT get , put = liftExceptT . put } соответственно вывести MonadState s m => Monad m можно, потому что это был суперкласс и он превратился в поле, а MonadState s (ExceptT m) в себе MonadState s m не содержит, имея на руках первый вы никак не получите второй. Определение data MonadState создается исключительно на основе определения класса, а там ничего про взаимоотношения ExceptT e m и m не сказано. То есть аналогия с обычным рекордом: у вас есть data Foo = Foo Int Int, вы создали x = Foo (fib 10) (fib 20), и теперь спрашиваете, как имея x вам получить fib, ведь она использовалась при его создании. Ответ - никак

Потому что механизм вывода работает в обратную сторону. Все написанные руками инстансы для mtl/transformers - которые и обеспечивают вывод, выглядят наподобие такого: instance MonadState s m => MonadState s (ExceptT m)

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Ребят в СИ можно реализовать ООП?
Николай
33
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Карта сайта