当在Polysemy.Sem值上使用时,Hint.interpret会给出编译器错误 [英] Hint.interpret gives a compiler error when used on a Polysemy.Sem value

查看:93
本文介绍了当在Polysemy.Sem值上使用时,Hint.interpret会给出编译器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编译多义使用提示( 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 that MyEffect is in fact Typeable.
  • 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. Rearranging MyEffect to type 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包装器模块,该模块使用ConsNil而不是标准列表语法.似乎与大多数问题相同,只是带有更详细的错误消息(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆