【问题标题】:How to make MonadError work with ghcjs/reflex如何使 MonadError 与 ghcjs/reflex 一起工作
【发布时间】:2018-06-19 14:13:10
【问题描述】:

我正在努力编译以下程序:

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

但是这个类似的版本也适用于 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 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’

仅供参考:我还没有完全掌握 Monad,很容易被这些错误吓到。救命!

【问题讨论】:

  • 使用来自 Reflex.Dom.Main 的签名 body::Widget () 有帮助吗?还是做main :: IO()?
  • 我得到的是这个: • 期望 'Widget ()' 再有一个参数 期望类型,但 'Widget ()' 有种类 '* -> *' • 在类型签名中:正文::小部件()

标签: haskell ghcjs reflex


【解决方案1】:

在 ghc 版本中,importStringIO monad do 语句的上下文中运行。 importString 能够在 IO monad 中返回一个值,所以编译器很高兴

在 ghcjs 版本中,importStringm monad do 语句的上下文中运行(mbody 的声明中指定)。 importString 无法在 m monad 中返回值,因此编译器会抱怨。

您可以通过使用 liftIOIO monad 值更改为 m monad 值来解决此问题。这是您的代码,其中包含此更改以及我为帮助自己理解代码而进行的一些其他更改。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 2021-12-19
    • 2012-05-29
    • 2018-05-17
    相关资源
    最近更新 更多