Changes between Version 49 and Version 50 of ExplicitCallStack


Ignore:
Timestamp:
Jan 30, 2007 5:18:47 PM (8 years ago)
Author:
guest
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • ExplicitCallStack

    v49 v50  
    7474 
    7575   d :: Int 
    76    d = e []                                               {- line 6 -} 
     76   d = e []                                      {- line 4 -} 
    7777 
    7878   e :: [Int] -> Int 
     
    8484                False -> hd 
    8585 
    86    hd = \x -> case x of                                   {- line 16 -} 
    87                  [] -> error "hd: empty list"             {- line 17 -} 
     86   hd :: [a] -> a 
     87   hd = \x -> case x of                          {- line 15 -} 
     88                 [] -> error "hd: empty list"    {- line 16 -} 
    8889                 (x:_) -> x 
    8990 
     
    9293                  True -> 1 
    9394                  False -> n * fac (n - 1) 
     95 
    9496}}} 
    9597 
     
    141143           hd: empty list 
    142144   Virtual stack trace: 
    143    (unknown)       {?}                                 
    144    (H.hs:17)       error "hd: empty..."                
    145    (H.hs:16)       (\..) [] | case []                 {- the case analysis of the list in hd -} 
    146    (H.hs:6)        (\..) []                           {- the application of hd in the body of d -} 
     145   (unknown)       {?} 
     146   (H.hs:16)       error "hd: empty..." 
     147   (H.hs:15)       (\..) [] | case []        {- case analysis of [] in hd -} 
     148   (H.hs:4)        (\..) []                  {- hd applied to [] in the body of d -} 
    147149   (unknown)       d 
    148150}}} 
     
    159161   Virtual stack trace: 
    160162   (unknown)       {?} 
    161    (I.hs:17)       error "hd: empty..." 
    162    (I.hs:16)       hd [] | case [] 
    163    (I.hs:6)        hd [] 
     163   (I.hs:16)       error "hd: empty..." 
     164   (I.hs:15)       hd [] | case [] 
     165   (I.hs:4)        hd [] 
    164166   (unknown)       d 
    165167}}} 
     
    181183   Virtual stack trace: 
    182184   (unknown)       {?} 
    183    (J.hs:17)       error "hd: empty..." 
    184    (J.hs:16)       hd [] | case [] 
    185    (J.hs:9)        hd [] 
    186    (J.hs:6)        e [] 
     185   (J.hs:16)       error "hd: empty..." 
     186   (J.hs:15)       hd [] | case [] 
     187   (J.hs:7)        hd [] 
     188   (J.hs:4)        e [] 
    187189   (unknown)       d 
    188190}}} 
     
    292294An advantage of this transformation style is that it handles combinations of transformed and untransformed functions easily. When variable expressions are transformed we simply check to see if the variable corresponds to a transformed function. If it does, we pass it the current stack value as an argument, otherwise we don't. 
    293295 
     296If you apply this transformation to the example above you get: 
     297{{{ 
     298   main = print d 
     299 
     300   d :: Int 
     301   d = e [] 
     302 
     303   e :: [Int] -> Int 
     304   e = f 10 
     305 
     306   f :: Int -> [Int] -> Int 
     307   f = \x -> case fac x < 10 of 
     308                True  -> \_ -> 3 
     309                False -> hd 
     310 
     311   hd :: [a] -> a 
     312   hd = \x -> case x of 
     313                 [] -> error "hd: empty list" 
     314                 (x:_) -> x 
     315 
     316   fac :: Int -> Int 
     317   fac = \n -> case n == 0 of 
     318                  True -> 1 
     319                  False -> n * fac (n - 1) 
     320}}} 
     321 
     322 
    294323A problem with this transformation style is that it is sensitive to the position of lambdas in the body of a declaration. For example, it transforms these two functions differently, even though they are semantically equivalent: 
    295324