当在Polysemy.Sem值上使用时,Hint.interpret会给出编译器错误 [英] Hint.interpret gives a compiler error when used on a Polysemy.Sem value
问题描述
我正在尝试编译多义使用提示( Language.Haskell .解释器).
I'm trying to compile Polysemy monad values at runtime using Hint (Language.Haskell.Interpreter).
当我尝试执行此操作时,在交互式"代码中,我确实收到有关错误使用:
运算符的错误;似乎文本提示传递给GHC时,语法上有错误.
When I try to do this I reliably get an error about improper use of the :
operator in "interactive" code; it seems as if the text hint is passing to GHC has a syntax error in it.
{-# 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,为了在解释器monad中传递
import
行,我必须在cabal沙盒外壳中运行此程序,因为Polysemy并未安装到我的机器上. - 也就是说,我认为阴谋集团或进口Polysemy并不是问题.如果我只是忽略导入Polysemy而仅导入
setImportsQ [("Prelude", Nothing)]
,则可以获得与上述完全相同的错误消息. - 我正在解释的字符串甚至不需要是有效的表达式;我可以将杂物放在那里,而不会更改错误.这向我表明问题出在
(as :: MyEffect)
. - 我加入了
typeOf
来证明MyEffect
实际上是Typeable
. - 我不知道为什么
typeOf exampleSem
给出这么长又怪异的类型签名.我确实认为这是问题所在.将MyEffect
重新排列为type MyEffect = Sem ((Embed IO) : []) ()
无效.
- I'm using cabal, and in order to pass the
import
line within the interpreter monad I have to run this from within a cabal sandboxed shell because Polysemy isn't installed to my machine at large. - That said, I don't think cabal or importing Polysemy is the problem. I can get the exact same error message as above if I just neglect to import Polysemy and just
setImportsQ [("Prelude", Nothing)]
. - The string I'm interpreting doesn't even need to be a valid expression; I can put jibberish in there without changing the error. This suggests to me that the problem is with
(as :: MyEffect)
. - I include
typeOf
to demonstrate thatMyEffect
is in factTypeable
. - I have no idea why
typeOf exampleSem
is giving such a long and weird type signature. I do think that this somehow is the problem. RearrangingMyEffect
totype MyEffect = Sem ((Embed IO) : []) ()
has no effect.
我做错什么了吗?我应该如何尝试调试此问题?
假设这是提示,一词多义或
Is it clear to anyone if I'm doing something wrong? How should I try to debug this problem?
Supposing this were a bug in hint, polysemy, or (less likely) in Type.Reflection.Typeable, what would my next step be to try to fix it? I assume I'd somehow have to pin down which library it is that having the problem?
这是对先前问题的改进. 这是原始内容.
This is a refinement of an earlier question. Here's the original.
推荐答案
不是答案,但是我发现了一些发现,可能对您有所帮助.
Not an answer, but I've made some discoveries which you might find helpful.
我认为这可能是虚假的前缀类型运算符语法': x xs
,它不是有效的Haskell(您必须将其写为infix或使用(':)
).因此,我实现了一个SemWorkaround
包装器模块,该模块使用Cons
和Nil
而不是标准列表语法.似乎与大多数问题相同,只是带有更详细的错误消息(hmm).
I thought it might be the bogus prefix type operator syntax ': x xs
which is not valid Haskell (you would have to either write it infix or use (':)
). So I implemented a SemWorkaround
wrapper module which used Cons
and Nil
instead of the standard list syntax. Seemed like mostly the same problem with a more verbose error message (hmm).
然后我认为这可能是显式的应用程序,因为错误消息不断谈论事物被赋予过多的参数.因此,我尝试将类型级别的列表表示形式更改为以前的处理方式.
Then I thought it might be the explicit kind application, since the error messages keep talking about things being given too many arguments. So I tried changing the type-level list representation to the way we used to do it back in the old days.
{-# LANGUAGE DataKinds, TypeOperators, TypeFamilies #-}
module SemWorkaround where
import Polysemy (Sem, Embed)
import Data.Kind (Type)
data Nil
data Cons (a :: (Type -> Type) -> Type -> Type) (as :: Type)
type family ListToList xs where
ListToList Nil = '[]
ListToList (Cons x xs) = x ': ListToList xs
newtype Sem' l a = Sem' { getSem' :: Sem (ListToList l) a }
并使用Sem'
整理提示边界.例如
And used Sem'
to marshal the hint boundary. E.g.
type MyEffect' = Sem' (Cons (Embed IO) Nil) ()
...
s <- interpret "Sem' . embed $ print \"Success\"" (as :: MyEffect')
pure $ getSem' s
这行得通.因此,似乎生成该类型的任何人都在为多态提升构造函数发出显式的实参,但是消费者期望它是隐式的.为了确认,我将变通方法模块更改为使用单态datakind List
.
This worked. So it seems like whoever is producing the type is emitting an explicit kind argument for polymorphic lifted constructors, but the consumer is expecting it to be implicit. To confirm I changed the workaround module to use a monomorphic datakind List
.
data List
= Nil
| Cons ((Type -> Type) -> Type -> Type) List
再次工作.
最后,我测试了infix问题,只是为了确保将其更改为:
Finally, I tested the infix problem just to be sure by changing it to:
data List
= Nil
| ((Type -> Type) -> Type -> Type) ::: List
令我惊讶的是,失败并显示了您熟悉的错误消息Operator applied to too few arguments
.因此,看来您发现了两个错误.有人不了解应该应该使用的多种类,而有人不应该理解应该使用的类型运算符.我还没有深入挖掘出谁是错人.
Which, to my surprise, failed with your familiar error message Operator applied to too few arguments
. So it seems you have found two bugs. Somebody doesn't understand polykinds who should, and somebody doesn't understand type operators who should. I haven't dug deep enough to find out who is wrong.
这篇关于当在Polysemy.Sem值上使用时,Hint.interpret会给出编译器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!