Я пытаюсь скомпилировать монадные значения Polysemy в время выполнения с использованием Hint (Language.Haskell.Interpreter< /а>).
Когда я пытаюсь это сделать, я надежно получаю сообщение об ошибке о неправильном использовании оператора :
в «интерактивном» коде; кажется, что текстовая подсказка, передаваемая GHC, содержит синтаксическую ошибку.
{-# LANGUAGE DataKinds #-}
module Main where
import Polysemy (Embed, embed, runM, Sem)
import Language.Haskell.Interpreter (as, interpret, Interpreter, runInterpreter, setImportsQ)
import Data.Typeable (typeOf)
import Control.Monad.IO.Class (liftIO)
main :: IO ()
main = do
-- Hint works fine to interpret a String:
m <- interpretWithErrors exampleHint
print m
-- And Sem works fine:
runM exampleSem
-- But notice the weird detected type:
print $ typeOf exampleSem
-- And now Hint fails to interpret a Sem:
s <- interpretWithErrors exampleBoth
print $ typeOf s
runM s
type MyEffect = Sem '[Embed IO] ()
exampleSem :: MyEffect
exampleSem = embed $ print "Successful Sem!"
exampleHint :: Interpreter String
exampleHint = do
setImportsQ [("Prelude", Nothing)]
interpret "\"Successful Hint!\"" (as :: String)
exampleBoth :: Interpreter MyEffect
exampleBoth = do
setImportsQ [("Prelude", Nothing), ("Polysemy", Nothing)]
liftIO $ print "Successfully imported!"
-- This is where it fails:
s <- interpret "embed $ print \"Success!\"" (as :: MyEffect)
liftIO $ print "Successfully interpreted!"
return s
interpretWithErrors :: Interpreter a -> IO a
interpretWithErrors i_a = do
e_e_a <- runInterpreter i_a
either (ioError . userError . show) (return) e_e_a
Запуск вышеуказанных отпечатков:
"Successful Hint!"
"Successful Sem!"
Sem (': ((* -> *) -> * -> *) (Embed IO) ('[] ((* -> *) -> * -> *))) ()
"Successfully imported!"
Hint-Polysemy: user error (WontCompile [GhcError {errMsg = "<interactive>:3:41: error: Operator applied to too few arguments: :"}])
Некоторые примечания:
- Я использую cabal, и для того, чтобы передать строку
import
в монаде интерпретатора, я должен запустить это из изолированной оболочки Cabal, потому что Polysemy не установлен на моей машине в целом. - Тем не менее, я не думаю, что клика или импорт Полисемии являются проблемой. Я могу получить то же самое сообщение об ошибке, что и выше, если просто пренебрег импортом Polysemy и просто
setImportsQ [("Prelude", Nothing)]
. - Строка, которую я интерпретирую, даже не обязательно должна быть допустимым выражением; Я могу вставить туда тарабарщину без изменения ошибки. Это наводит меня на мысль, что проблема с
(as :: MyEffect)
. - Я включаю
typeOf
, чтобы продемонстрировать, чтоMyEffect
на самом делеTypeable
. - Я понятия не имею, почему
typeOf exampleSem
дает такую длинную и странную подпись типа. Я думаю, что это как-то проблема. ПерестановкаMyEffect
вtype MyEffect = Sem ((Embed IO) : []) ()
не дает результата.
Кому-нибудь понятно, что я делаю что-то не так? Как мне попытаться отладить эту проблему?
Предположим, это ошибка в подсказке, полисемии или (что менее вероятно) в Type.Reflection.Typeable, каким будет мой следующий шаг, чтобы попытаться это исправить? Я предполагаю, что мне как-то придется определить, в какой библиотеке возникла проблема?
Это уточнение предыдущего вопроса. Вот оригинал.
set [languageExtensions := [DataKinds, TypeOperators]]
в начало каждого монадного выражения интерпретатора; это не меняет поведение. - person ShapeOfMatter   schedule 27.12.2019