Tutorial / Guidance on getting Yesod working with interactive debugging in GHCi

318 views
Skip to first unread message

Simon Gardner

unread,
Jun 27, 2014, 5:15:36 AM6/27/14
to yeso...@googlegroups.com
I've asked this same question as a Yesod github issue. I've since realised that's probably not the best place. Sorry about that !

The thing that is most slowing down my learning of Haskell / Yesod is my inability to do interactive debugging. Surprisingly, there doesn't seem to be any clear tutorials (or even any tutorials?) about how to go about doing this with Yesod.

It seems like I should be able to do something like:

cabal clean
cabal repl
:break Handler.myHandler 95
:main

and that should work ? unfortunately :main fails with a "not in scope `main`"

I've found this: https://github.com/chrisdone/ghci-reload-demo which seems ideal in terms of developer friendliness but having similar difficulty getting it to work.

I've installed the foreign-store-0.1 module, updated my scafford with app/DevelMain.hs and updated my .cabal file with warp and foreign-store as suggested.

I'm failing at the last hurdle which is being able to run DevelMain. This is almost certainly my total lack of knowledge but I'm sure I can't be the only one who is / will struggle with this?

:l DevelMain.hs (and various combinations like app.DevelMain.hs etc) all fail with "Failed, modules loaded: none"

I've added a **TODO into this wiki page (hope you don't mind). If someone were to help me get ghci debugging working, I'd be happy to turn the experience into some decent (ie beginner level) documentation for the wiki :)

Many thanks

Greg Weber

unread,
Jun 27, 2014, 9:23:19 AM6/27/14
to Yesod Web Framework
Thanks for asking, I will add documentation to the scaffold file. It would be great if you can keep updating the wiki.
The workflow is just:

:l DevelMain
DevelMain.update


--
You received this message because you are subscribed to the Google Groups "Yesod Web Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to yesodweb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Simon

unread,
Jun 27, 2014, 9:32:41 AM6/27/14
to yeso...@googlegroups.com
Thanks for answering :)

I had my DevelMain.hs in the app folder (which I thought I'd read somewhere in the discussions would be the case in the released software?).

Either way, moving DevelMain.hs to the root folder got the :l to find the module.

Unfortunately, I now get some compilation errors.

DevelMain.hs:32:11: Not in scope: type constructor or class `IO'

DevelMain.hs:37:7: Not in scope: data constructor `Nothing'

DevelMain.hs:41:11: Not in scope: `return'

DevelMain.hs:43:7: Not in scope: data constructor `Just'

DevelMain.hs:45:38: Not in scope: `$'

DevelMain.hs:47:44: Not in scope: `>>'

DevelMain.hs:47:67: Not in scope: `>>='

DevelMain.hs:52:51: Not in scope: type constructor or class `IO'

DevelMain.hs:52:60: Not in scope: type constructor or class `IO'

DevelMain.hs:53:49: Not in scope: `$'

DevelMain.hs:55:13: Not in scope: `>>='

DevelMain.hs:59:10: Not in scope: type constructor or class `IO'
Failed, modules loaded: Application, Import, Settings, Handler.Home, Handler.Users, Handler.Property, Handler.Media, Foundation, Settings.Development, Settings.StaticFiles, Model.



--
You received this message because you are subscribed to a topic in the Google Groups "Yesod Web Framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/yesodweb/UaCxPcNwi2o/unsubscribe.
To unsubscribe from this group and all its topics, send an email to yesodweb+u...@googlegroups.com.

Greg Weber

unread,
Jun 27, 2014, 9:44:06 AM6/27/14
to Yesod Web Framework
add  this to the library section of the cabal file:

  hs-source-dirs:  .,  app

And then you will need to add this to DevelMain.hs

  import Prelude

I just added these changes to the scaffold now

Simon Gardner

unread,
Jun 27, 2014, 9:56:03 AM6/27/14
to yeso...@googlegroups.com
OK, that worked, almost :)

weirdly, when the code containing the breakpoint is hit I get a "*** Ignoring breakpoint" message in the console  :)

Greg Weber

unread,
Jun 27, 2014, 10:14:35 AM6/27/14
to Yesod Web Framework
I have never used ghci breakpoints. Instead I just use print statements (and the debug helper from the file-location package).
However, the documentation says the module must be interpreted. So you either don't want to use -fobject-code to begin with or need to figure out how to interpret the module with the breakpoint.

Simon

unread,
Jun 27, 2014, 10:23:12 AM6/27/14
to yeso...@googlegroups.com
pretty sure the code *is* being interpreted because:

a) :l DevelMain prints various messages like 

[ 8 of 12] Compiling Handler.Users    ( Handler/Users.hs, interpreted )

b) If the code isn't being interpreted you get an error when you add a breakpoint suggesting that you run "add *whatever" to load the module in interpreted mode.

Frustratingly, I can't even get Debug.trace to work because it complains of type errors when ever I try to print something :(. Interactive debugging has to be the way forward?


--

Greg Weber

unread,
Jun 27, 2014, 10:37:37 AM6/27/14
to Yesod Web Framework
This works for me (note that -fobject-code is not given to ghc-options, that keeps everything interpreted).

cabal repl --ghc-options="-O0"
*Application> :l Handler.Read
*Handler.Read> :break 35
Breakpoint 0 activated at Handler/Read.hs:35:21-42


--
You received this message because you are subscribed to the Google Groups "Yesod Web Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to yesodweb+u...@googlegroups.com.

Simon Gardner

unread,
Jun 27, 2014, 10:49:26 AM6/27/14
to yeso...@googlegroups.com
>Breakpoint 0 activated at Handler/Read.hs:35:21-42

yes, I get that far.

it's when I hit the breakpoint by requesting the url associated with the handler that I get the

*** Ignoring breakpoint

Simon Gardner

unread,
Jun 27, 2014, 2:44:57 PM6/27/14
to yeso...@googlegroups.com
could it be something to do with "cabal repl" ?
I can use the debugger fine with just ghci and a toy program as per the ghci debugging instructions?

Greg Weber

unread,
Jun 28, 2014, 9:47:25 AM6/28/14
to Yesod Web Framework
On Fri, Jun 27, 2014 at 11:44 AM, Simon Gardner <slg...@gmail.com> wrote:
could it be something to do with "cabal repl" ?
 
You could try proving that by using cabal repl with your toy program.

But you should definitely learn how to just use print and trace statements.

Simon Gardner

unread,
Jun 28, 2014, 10:34:35 AM6/28/14
to yeso...@googlegroups.com
>You could try proving that by using cabal repl with your toy program.


I get an error message: No modules are loaded with debugging support.

(The module is definitely loaded as "interpreted".

>But you should definitely learn how to just use print and trace statements.

I agree that I should learn but even this has proved to be frustratingly difficult ! 

Whilst it's (obviously) possible to work without one, I would have thought an interactive debugging environment would be a fundamental requirement? 

Rehno Lindeque

unread,
Jun 28, 2014, 11:11:03 AM6/28/14
to yeso...@googlegroups.com
Just wanted to add this for reference https://gist.github.com/rehno-lindeque/10490026 - it's not close to being polished / comprehensive though, just a few things I quickly knocked up a while ago. I've yet to incorporate ideas from https://github.com/chrisdone/ghci-reload-demo and also this thread :)

Greg Weber

unread,
Jun 30, 2014, 2:14:50 AM6/30/14
to Yesod Web Framework


On Jun 28, 2014 7:34 AM, "Simon Gardner" <slg...@gmail.com> wrote:
>
> >You could try proving that by using cabal repl with your toy program.
>
> Yeah, I've tried, using the qsort example from https://www.haskell.org/ghc/docs/7.6.3/html/users_guide/ghci-debugger.html
>
> I get an error message: No modules are loaded with debugging support.
>
> (The module is definitely loaded as "interpreted".
>
> >But you should definitely learn how to just use print and trace statements.
>
> I agree that I should learn but even this has proved to be frustratingly difficult ! 
>
> Whilst it's (obviously) possible to work without one, I would have thought an interactive debugging environment would be a fundamental requirement? 
>

A debugger is mostly isomorphic to print statements, just more efficient.

It looks like you are not getting the answers you need, but at this point the questions are not yesod specific so you can try asking elsewhere.

>
>
>
> On Saturday, 28 June 2014 14:47:25 UTC+1, Greg Weber wrote:
>>
>> On Fri, Jun 27, 2014 at 11:44 AM, Simon Gardner <slg...@gmail.com> wrote:
>>>
>>> could it be something to do with "cabal repl" ?
>>
>>  
>> You could try proving that by using cabal repl with your toy program.
>>
>> But you should definitely learn how to just use print and trace statements.
>

Simon

unread,
Jun 30, 2014, 2:54:39 AM6/30/14
to yeso...@googlegroups.com
>A debugger is mostly isomorphic to print statements, just more efficient.

yes, and that's a big deal.

>It looks like you are not getting the answers you need, but at this point the questions are not yesod specific so you can try asking elsewhere.

I have debugging working fine in ghci with plain Haskell, but for some reason not with Yesod (or maybe it's cabal repl). Either way, surely this group is the best place to ask that question?

Presumably somebody must have ghci debugging working with Yesod? If so, what are they doing / not doing differently from me? If no-one is using ghci debugging with Yesod, that's interesting (and strange?) by itself.

Thanks for taking the time to reply Greg :)




--
You received this message because you are subscribed to a topic in the Google Groups "Yesod Web Framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/yesodweb/UaCxPcNwi2o/unsubscribe.
To unsubscribe from this group and all its topics, send an email to yesodweb+u...@googlegroups.com.

Greg Weber

unread,
Jun 30, 2014, 10:10:32 AM6/30/14
to Yesod Web Framework


On Jun 29, 2014 11:54 PM, "Simon" <slg...@gmail.com> wrote:
>
> >A debugger is mostly isomorphic to print statements, just more efficient.
>
> yes, and that's a big deal.
>
> >It looks like you are not getting the answers you need, but at this point the questions are not yesod specific so you can try asking elsewhere.
>
> I have debugging working fine in ghci with plain Haskell, but for some reason not with Yesod (or maybe it's cabal repl). Either way, surely this group is the best place to ask that question?
>
> Presumably somebody must have ghci debugging working with Yesod? If so, what are they doing / not doing differently from me? If no-one is using ghci debugging with Yesod, that's interesting (and strange?) by itself.

I have never heard anyone speak of using the ghci debugger. Debuggers are great for dealing with code you don't understand. If I can't understand my code by adding one or two print statements that's because it is poorly written so I clean it up by adding types, refactoring, and adding tests. A debugger would be a lot more useful for investigating libraries, but it is better to be in the mindset that you own those and they are part of your app.

Simon

unread,
Jun 30, 2014, 10:30:39 AM6/30/14
to yeso...@googlegroups.com
>The thing that is most slowing down my learning of Haskell / Yesod is my inability to do interactive debugging.

>Debuggers are great for dealing with code you don't understand.

ah, so you see where I'm coming from :p ?

Rehno Lindeque

unread,
Jul 2, 2014, 7:34:31 AM7/2/14
to yeso...@googlegroups.com
As I mentioned earlier, I am using ghci (via cabal repl) with yesod. Unfortunately I don't know what the problem is that you're running into but if you do end up creating any helpers for interactively testing, please share :)

Simon

unread,
Jul 2, 2014, 8:59:01 AM7/2/14
to yeso...@googlegroups.com
I asked the question about how to run yesod via GHCi on #yesod IRC.

I ended up getting the following script from darthdeus via dxl3a:

#!/bin/sh
(
    grep '^import' devel.hs;
    while [ true ]; do
        echo "Reload" >&2;
        echo ':load Application';
        echo 'getApplicationDev >>= \(port, app) -> runSettings (setPort port defaultSettings) app';
        inotifywait -e close_write **/** >/dev/null;
        pkill -n --signal SIGINT ghc;
        sleep 0.5;
    done
) | cabal repl lib:<your_application>

This provides a very neat autoreload whenever any files change and it's extremely fast - unlike the 5 - 10+ seconds that yesod devel -dev takes to reload. 

Hard to imagine why yesod devel doesn't use GHCi with something like the above ?

I haven't tried to adapt this yet to get debugging working but I can see how it might be possible.

Michael Sloan

unread,
Jul 2, 2014, 9:40:32 AM7/2/14
to yeso...@googlegroups.com
You can make an approach like this go even faster, avoiding killing and restarting ghci, by using something like this:

> pid <- forkProcess $ getApplicationDev >>= \(port, app) -> runSettings (setPort port defaultSettings) app
> signalProcess sigKILL pid
> :reload

This leads to very fast reloads, and reliably kills all of the threads started by the process.  My code that drives this is quite application specific and not public, but I hope this helps!

-Michael

Rehno Lindeque

unread,
Jul 2, 2014, 2:10:51 PM7/2/14
to yeso...@googlegroups.com
Thanks to both of you, I'll try and publish things in our setup in gists (or add to the scaffold if that makes sense) once it starts to get a bit polished.

Артур Файзрахманов

unread,
Jul 3, 2014, 7:35:11 AM7/3/14
to yeso...@googlegroups.com
Can someone help to adopt this script to OS X Mavericks? I have no `inotifywait` command.

Greg Weber

unread,
Jul 3, 2014, 9:22:25 AM7/3/14
to Yesod Web Framework
You can use fsnotify to do file watching from Haskell. Look for watchTree in this gist:


On Thu, Jul 3, 2014 at 4:35 AM, Артур Файзрахманов <hera...@gmail.com> wrote:
Can someone help to adopt this script to OS X Mavericks? I have no `inotifywait` command.

--

N/A Jamesb

unread,
Jul 4, 2014, 5:33:41 AM7/4/14
to yeso...@googlegroups.com
> pid <- forkProcess $ getApplicationDev >>= \(port, app) -> runSettings (setPort port defaultSettings) app
> signalProcess sigKILL pid
> :reload

That's interesting! I could try to integrate this idea in my script (actually I'm d3lxa the author of the script above posted by Simon). There is small hack with this sleep, I think it's useless anyway because the output is buffered through the pipe.



On Thursday, July 3, 2014 1:35:11 PM UTC+2, Артур Файзрахманов wrote:
Can someone help to adopt this script to OS X Mavericks? I have no `inotifywait` command.

I've read you can use fswatch on mac but it's directory-oriented so I'm not sure it's so trivial. Anyway that's true we should use the fsnotify library from Haskell, it's portable. By the way I was wondering why I have such high load with yesod-devel, it's idling but still using like 5-10% of CPU, it may be related to a bad implementation from fsnotify or a loop inside yesod-bin, if anyone can inform me? The script I proposed above has no CPU utilisation and is lighting fast and I hope it can be implemented in Haskell if possible (for portability and integration) without the idle load.

Reply all
Reply to author
Forward
0 new messages