Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile error when trying some Yesod examples

Tags:

haskell

yesod

I am trying Yesod book examples documented on Yesod webpage. One of the examples is for Chat application embedded in Wiki. When I try it in ghci (loading Chat module from Wiki.hs which contains Wiki example code), I get the error below for 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) [])),
        ....]'

I am not very familiar with Yesod libraries yet. So, I am stumped by the above error - I have seen this error in other Yesod examples too where toWidget function is called. So, it seems to be related to toWidget function. I will appreciate help in fixing the above error.

I am using ghc 7.6.1 with yesod 1.1.4.1.

Update:

Fixed following Hammar's suggestion. I made two changes in Chat.hs.

  1. Add import statement for rawJS:

    import Text.Julius (rawJS)

  2. Track down all instances of #{} blocks within julius whamlet in Chat.hs, and replace them with {# rawJS ...}

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

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

like image 585
Sal Avatar asked Nov 30 '12 20:11

Sal


2 Answers

I don't have Yesod installed to test it at the moment, but according to this blog post you should just have to change #{output} to #{rawJS output} and so on when interpolating JavaScript identifiers.

like image 190
hammar Avatar answered Oct 24 '22 23:10

hammar


In shakespeare-js-1.1.0, the ToJavascript instances for Text and some other types have been removed:

-- | 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

while in previous versions of the package, they were only conditionally disabled:

#ifndef SAFER_INTERPOLATION

I don't know whether that's intentional and meant to remain so, or just a forgotten development change.

To use the example as is, you would need to rebuild yesod against shakespeare-js < 1.1. That would mean uninstalling a lot of packages first, or a new sandbox (if you're using cabal-dev or some other sandboxing tool).

The only instances of ToJavascript in shakespeare-js-1.1.0 are RawJavascript (a newtype wrapper around Builder) and Value (a type for JSON values) from the aeson package.

You could just wrap output in

Text.Julius.toJavascript output

in a RawJavascript . Data.Text.Lazy.Builder.fromText to get a RawJavascript value and make it work if it were real code, but since it's TH-generated, you'd need to fix the TH output or the quasiquoter - neither of which I know how to do.

like image 21
Daniel Fischer Avatar answered Oct 24 '22 22:10

Daniel Fischer