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

Привет всем! Первый раз тут, столкнулся с некой проблемой. Пишу интерпретатор

брейнфака. У меня есть функция run которая делает пошаговое исполнение операций.
type Interrupt r a = ProgramState a -- ^ state of interpreter at the moment of interrupt
-> (ProgramState a -> Cont r (ProgramState a)) -- ^ return continuation
-> Cont r (ProgramState a)

-- step by step interpretation of the program from the given 'ProgramState a'
run :: (Num a, Ord a, Eq a) => ProgramState a
-> Interrupt r a -- ^ Print interrupt
-> Interrupt r a -- ^ Write interrupt
-> Cont r (ProgramState a)
run ps printI writeI = let code = getCode ps in
case currentInstruction $ getCode ps of
MoveCell n -> return . setCode (shiftRCode code) $ move (fromIntegral n) ps
ChangeCell n -> return . setCode (shiftRCode code) $ change (fromIntegral n) ps
PrintCell -> do
ps' <- callCC $ \ret -> printI ps ret
return $ setCode (shiftRCode code) ps'
WriteCell -> do
ps' <- callCC $ \ret -> writeI ps ret
return $ setCode (shiftRCode code) ps'
LoopL -> let Memory {..} = getMemory ps
code = getCode ps
in case current of
0 -> return $ seekLoopR ps
_ -> return . flip setCode ps $ shiftRCode code
LoopR -> let Memory {..} = getMemory ps
code = getCode ps
in case current of
0 -> return . flip setCode ps $ shiftRCode code
_ -> return $ seekLoopL ps
End -> return ps
Проблема заключается в том, что я не хочу привносить в нее еффекты только ради двух операторов (WriteCell и PrintCell), так как 80% этой функции абсолютно "чисты". Моя идея для решении этой проблемы заключалась в использовании прерываний, чтобы мочь остановить выполнение функции в нужный момент, передать контрол флоу какой-то effectfull функции(вместе со снапшотом состояния программы ProgramState a), которая может изменить это состояние и вернуть выполнение обратно в run. Так вот, в принципе это работает, но у меня не получается совместить это с еффектами, так как мне нужно значение из внешнего мира, а это означает, что мое прерывание должно иметь тип, который позволит достать это значениче(например IO a означаент, что прерывание должно быть в IO, чтобы я мог достать и использовать a).

Есть какие-то идеи как это решить?

5 ответов

11 просмотров

Завернуть всё в Sem m из polysemy, потребовать самопальные эффекты Writes и Prints

p3rsik- Автор вопроса
p3rsik
тогда она будет не чистой

Это ещё почему, runWritesPure :: Sem (Writes : m) a -> Sem m (a, [String]) и потом в run :: Sem '[] a -> a и будет чистая функция

p3rsik- Автор вопроса
TOV_MULTIMASSO
Это ещё почему, runWritesPure :: Sem (Writes : m) ...

честно говоря не знаком с polysemy, но я предполагаю что работает это также как в free, где ты пишешь дсл, а потом можешь писать интерпретаторы в любой конечный стек

p3rsik
тогда она будет не чистой

бтв по этому поводу можно поспорить

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта