Я работаю над внедрением встроенного DSL в PureScript, используя стиль «наконец без тегов». Репо можно найти по адресу: https://github.com/afcondon/purescript-finally-tagless-exКак реализовать Monadic экземпляр «окончательного бездепозитного» типа в PureScript?
В этом проблема. Учитывая абстрактное определение очень упрощенной файловой системы:
class (Monad m) <= MonadFileSystem m where
cd :: FilePath -> m Unit
ls :: m (Array (Tuple FilePath FileType))
cat :: Array FilePath -> m String
можно легко обеспечить реализацию таких, как этот (https://github.com/afcondon/purescript-finally-tagless-ex/blob/master/MonadicEx/src/FakeFileSystem.purs), который может быть использован в качестве встроенного языка и интерпретированы (или пробега) для оценки в виде строки (альтернативно, вы можете сделать статический анализ структуры вместо того, чтобы превратить его в строку).
В принципе, можно также иметь пример побочного эффекта, который фактически взаимодействует с файловой системой, но который может «интерпретировать» точно такой же встроенный язык. Я бы хотел использовать purescript-node-fs
для этого, что означало бы принятие Eff (fs :: FS, err :: EXCEPTION | eff)
.
Мой вопрос - как реально реализовать «настоящий», эффектный экземпляр? вам нужно изменить подписи cd
, ls
и cat
? или вы можете каким-то образом оценить всю монаду в Eff
, чтобы эти функции не переносили Eff
в свою подпись?
Большое спасибо за подробный ответ (ы). Первый, безусловно, работает только для побочных эффектов, я все еще испытываю трудности с формулировкой его таким образом, что он имеет контекст, такой как текущий рабочий каталог, который вам нужен во многих ситуациях. Я попробовал взломать что-то похожее на пример Zipper из экземпляра FakeFS, но это сломает все отличные новые типы. Второе решение действительно прекрасное и выразительное, но, похоже, генерирует (ложную?) Ошибку сиротского экземпляра, за исключением случаев, когда Colocated с AbstractFileSystem? –
Верно, что вам нужно будет определить последнюю, а также «MonadFileSystem», чтобы избежать сиротской ошибки (другое не-сиротное место для нее было бы в модуле с «Эффектом», очевидно, это не вариант!), Но учитывая ваш следующий вопрос здесь, похоже, что вам, вероятно, понадобится «StateT» вокруг «Eff» для поддержки cwd и т. д., и в этом случае я, вероятно, поеду на маршрут «newtype», который позволит избежать проблемы с сиротой слишком. –