【问题标题】:Compile error when trying some Yesod examples尝试一些 Yesod 示例时编译错误
【发布时间】:2012-11-19 03:14:41
【问题描述】:

我正在尝试 Yesod 网页上记录的 Yesod 书籍示例。其中一个例子是Chat application embedded in Wiki。当我在 ghci 中尝试时(从包含 Wiki 示例代码的 Wiki.hs 加载 Chat 模块),我收到以下 Chat.hs 错误:

Chat.hs:122:34:
    Could not deduce (Text.Julius.ToJavascript Text)
      arising from a use of `Text.Julius.toJavascript'
    from the context (YesodChat master)
      bound by the type signature for
                 chatWidget :: YesodChat master =>
                               (Route Chat -> Route master) -> GWidget sub master ()
      at Chat.hs:(81,15)-(83,35)
    Possible fix:
      add an instance declaration for (Text.Julius.ToJavascript Text)
    In the first argument of `Text.Julius.Javascript', namely
      `Text.Julius.toJavascript output'
    In the expression:
      Text.Julius.Javascript (Text.Julius.toJavascript output)
    In the first argument of `Data.Monoid.mconcat', namely
      `[Text.Julius.Javascript
          ((Data.Text.Lazy.Builder.fromText . Text.Shakespeare.pack')
             "\
             \// Set up the receiving end\
             \var output = document.getElementById(\""),
        Text.Julius.Javascript (Text.Julius.toJavascript output),
        Text.Julius.Javascript
          ((Data.Text.Lazy.Builder.fromText . Text.Shakespeare.pack')
             "\");\
             \var src = new EventSource(\""),
        Text.Julius.Javascript
          (Data.Text.Lazy.Builder.fromText
             (_render_a3Yr (toMaster ReceiveR) [])),
        ....]'

我对 Yesod 库还不是很熟悉。所以,我被上述错误难住了——我在其他 Yesod 示例中也看到了这个错误,其中调用了 toWidget 函数。所以,它似乎与toWidget 函数有关。我将感谢您在修复上述错误方面的帮助。

我正在使用 ghc 7.6.1yesod 1.1.4.1

更新:

按照 Hammar 的建议进行了修复。我在Chat.hs 中做了两处更改。

  1. 为 rawJS 添加导入语句:

    import Text.Julius (rawJS)

  2. Chat.hs 中跟踪julius whamlet 内的所有#{} 块实例,并将它们替换为{# rawJS ...}

    var output = document.getElementById("#{rawJS output}");

    var input = document.getElementById("#{rawJS input}");

【问题讨论】:

    标签: haskell yesod


    【解决方案1】:

    shakespeare-js-1.1.0 中,已删除ToJavascriptText 和其他一些类型的实例:

    -- | A typeclass for types that can be interpolated in CoffeeScript templates.
    class ToJavascript a where
        toJavascript :: a -> Builder
    #if 0
    instance ToJavascript [Char] where toJavascript = fromLazyText . TL.pack
    instance ToJavascript TS.Text where toJavascript = fromText
    instance ToJavascript TL.Text where toJavascript = fromLazyText
    instance ToJavascript Javascript where toJavascript = unJavascript
    instance ToJavascript Builder where toJavascript = id
    #endif
    instance ToJavascript Value where toJavascript = fromValue
    

    在以前版本的包中,它们只是有条件地被禁用:

    #ifndef SAFER_INTERPOLATION
    

    我不知道这是否是故意的并且打算一直如此,或者只是一个被遗忘的发展变化。

    要按原样使用示例,您需要针对 shakespeare-js < 1.1 重建 yesod。这意味着首先卸载很多包,或者一个新的沙箱(如果您使用的是 cabal-dev 或其他一些沙箱工具)。

    shakespeare-js-1.1.0ToJavascript 的唯一实例是 aeson 包中的 RawJavascriptnewtype 围绕 Builder 的包装器)和 Value(JSON 值的类型)。

    你可以把output 包裹起来

    Text.Julius.toJavascript output
    

    RawJavascript . Data.Text.Lazy.Builder.fromText 中获取RawJavascript 值并使其工作(如果它是真实代码),但由于它是 TH 生成的,您需要修复 TH 输出或准引用器 - 我都不知道怎么办。

    【讨论】:

    • 谢谢@daniel-fischer。确实,正如 Hammar 指出的那样,rawJS 缺失了。
    【解决方案2】:

    我目前没有安装 Yesod 来测试它,但根据 this blog post 你应该只需要在插入 JavaScript 标识符时将 #{output} 更改为 #{rawJS output} 等等。

    【讨论】:

    • 谢谢你,@hammar。这正是问题所在。在我追踪 julius whamlet 中的每个 #{} 块并将其替换为 rawJS 后,现在已修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多