From 45b04f650e6985c524301112a8381a1aff808fc6 Mon Sep 17 00:00:00 2001 From: Pepe Iborra Date: Thu, 26 Apr 2007 09:37:19 +0000 Subject: [PATCH] New section on debugging lambdas in the ghci user guide --- docs/users_guide/ghci.xml | 124 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 19 deletions(-) diff --git a/docs/users_guide/ghci.xml b/docs/users_guide/ghci.xml index 61aa513..54ce6b7 100644 --- a/docs/users_guide/ghci.xml +++ b/docs/users_guide/ghci.xml @@ -1831,22 +1831,90 @@ x :: Int - Limitations - - - - Implicit parameters (see ) are only available - at the scope of a breakpoint if there is a explicit type signature. - - - - - Modules compiled by GHCi under the -fdebugging - flag will perform slower: the debugging mode introduces some overhead. - Modules compiled to object code by ghc are not affected. - - - + Debugging Higher-Order functions + It is possible to use the debugger to examine lambdas. + When we are at a breakpoint and a lambda is in scope, the debugger cannot show + you the source code that constitutes it; however, it is possible to get some + information by applying it to some arguments and observing the result. + + The process is slightly complicated when the binding is polymorphic. + We will use a example to show the process. + To keep it simple, we will use the well known map function: + +import Prelude hiding (map) + +map :: (a->b) -> a -> b +map f [] = [] +map f (x:xs) = f x : map f xs + + We set a breakpoint on map, and call it. + +*Main> :break map +Breakpoint 0 activated at map.hs:(4,0)-(5,12) +*Main> map Just [1..5] +Stopped at map.hs:(4,0)-(5,12) +_result :: [b] +x :: a +f :: a -> b +xs :: [a] + + GHCi tells us that, among other bindings, f is in scope. + However, its type is not fully known yet, + and thus it is not possible to apply it yet to any + arguments. Nevertheless, observe that the type of its first argument is the + same as the type of x, and its result type is the + same as the type of _result. + The debugger has some intelligence built-in to update the type of + f whenever the types of x or + _result are reconstructed. So what we do in this scenario is + force x a bit, in order to recover both its type + and the argument part of f. + +*Main> seq x () +*Main> :print x +x = 1 + + We can check now that as expected, the type of x + has been reconstructed, and with it the + type of f has been too: + +*Main> :t x +x :: Integer +*Main> :t f +f :: Integer -> b + + From here, we can apply f to any argument of type Integer and observe the + results. + let b = f 10 +*Main> :t b +b :: b +*Main> b +:1:0: + Ambiguous type variable `b' in the constraint: + `Show b' arising from a use of `print' at :1:0 +*Main> :p b +b = (_t2::a) +*Main> seq b () +() +*Main> :t b +b :: a +*Main> :p b +b = Just 10 +*Main> :t b +b :: Maybe Integer +*Main> :t f +f :: Integer -> Maybe Integer +*Main> f 20 +Just 20 +*Main> map f [1..5] +[Just 1, Just 2, Just 3, Just 4, Just 5] + ]]> + In the first application of f, we had to do + some more type reconstruction + in order to recover the result type of f. + But after that, we are free to use + f normally. Tips @@ -1865,8 +1933,8 @@ x :: Int type MyLongType a = [Maybe [Maybe a]] -main:Main> :m +GHC.Exts -main:Main> main +*Main> :m +GHC.Exts +*Main> main Local bindings in scope: x :: a Main.hs:15> let x' = unsafeCoerce x :: MyLongType Bool @@ -1885,7 +1953,25 @@ Main.hs:15> x' - + + Limitations + + + + Implicit parameters (see ) are only available + at the scope of a breakpoint if there is a explicit type signature. + + + + + Modules compiled by GHCi under the -fdebugging + flag will perform slower: the debugging mode introduces some overhead. + Modules compiled to object code by ghc are not affected. + + + + + The <filename>.ghci</filename> file .ghcifile -- 1.7.10.4