[英]How to make MonadError work with ghcjs/reflex
I'm struggling to compile the following program: 我正在努力编译以下程序:
import Data.Maybe
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Data.URLEncoded
import Reflex.Dom
url :: T.Text
url = T.pack "parm1=one&parm2=two"
main = do
mainWidget body
body :: MonadWidget t m => m ()
body = el (T.pack "div") $ do
-- let t = (T.pack "this program works if you replace the line below with this")
t <- fmap (T.pack . fromMaybe "" . Data.URLEncoded.lookup "parm2") (importString (T.unpack url))
text t
however this similar version works with vanilla ghc 但是,此类似版本适用于Vanilla ghc
import Data.Maybe
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Data.URLEncoded
url :: T.Text
url = T.pack "parm1=one&parm2=two"
main = do
body
body = do
t <- fmap (T.pack . fromMaybe "" . Data.URLEncoded.lookup "parm2") (importString (T.unpack url))
T.putStrLn t
The compiler says something is ambiguous and I'm not really sure how to implement these to work. 编译器说有些含糊不清,我不确定如何实现这些功能。
The type variable ‘e0’ is ambiguous
Relevant bindings include body :: m () (bound at reflex.hs:14:1)
These potential instances exist:
instance [safe] Control.Monad.Error.Class.MonadError e (Either e)
-- Defined in ‘Control.Monad.Error.Class’
...plus 13 instances involving out-of-scope types
instance [safe] Control.Monad.Error.Class.MonadError
GHC.IO.Exception.IOException IO
-- Defined in ‘Control.Monad.Error.Class’
instance [safe] (Monad m, Control.Monad.Trans.Error.Error e) =>
Control.Monad.Error.Class.MonadError
e (Control.Monad.Trans.Error.ErrorT e m)
-- Defined in ‘Control.Monad.Error.Class’
FYI: I haven't fully grasped Monads yet and easily get scared with these errors. 仅供参考:我还没有完全掌握Monad,并且容易被这些错误吓到。 Help!
救命!
In the ghc version, importString
is operating in the context of an IO
monad do statement . 在ghc版本中,
importString
在IO
monad do语句的上下文中运行。 importString
is capable of returning a value in the IO
monad so the compiler is happy importString
能够在IO
monad中返回值,因此编译器很高兴
In the ghcjs version, importString
is operating in the context of an m
monad do statement ( m
is specified in the declaration of body
). 在ghcjs版本,
importString
是在上下文操作m
单子做陈述( m
中的声明中指定body
)。 importString
has no way to return a value in the m
monad so the compiler complains. importString
无法在m
monad中返回值,因此编译器会抱怨。
You can get around this by using liftIO
to change an IO
monad value to a m
monad value. 您可以通过使用
liftIO
将IO
monad值更改为m
monad值来解决此问题。 Here's your code with this change and a few other changes that I made to help myself understand the code. 这是您进行此更改的代码,以及我为了帮助自己理解代码而进行的其他一些更改。
import Data.Maybe
import qualified Data.Text as T
import Data.URLEncoded as DU
import Reflex.Dom
import Control.Monad.Trans as CMT
url :: T.Text
url = T.pack "parm1=one&parm2=two"
main = do
mainWidget body
body :: MonadWidget t m => m ()
body = el (T.pack "div") $ do
let istr = CMT.liftIO $ DU.importString (T.unpack url)
t <- fmap (T.pack . fromMaybe "" . DU.lookup "parm2") istr
text t
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.