Changes between Version 1 and Version 2 of Holes


Ignore:
Timestamp:
Feb 9, 2012 8:05:23 PM (2 years ago)
Author:
xnyhps
Comment:

Used a bit better example, updated info on implicit parameters

Legend:

Unmodified
Added
Removed
Modified
  • Holes

    v1 v2  
    3939{{{ 
    4040test :: [Bool] 
    41 test = undefined : undefined : [] 
     41test = undefined : (undefined ++ []) 
    4242}}} 
    4343 
     
    4949Same example: 
    5050{{{ 
    51 test = ?a : ?b : [] 
     51test = ?a : (?b ++ []) 
    5252}}} 
    5353 
     
    5555 
    5656{{{ 
    57 > :t let test = ?a : ?b : [] in test :: [Bool] 
    58 let test = ?a : ?b : [] in test :: [Bool] 
    59   :: (?a::Bool, ?b::Bool) => [Bool] 
     57> :t let test = ?a : (?b ++ []) in test :: [Bool] 
     58let test = ?a : (?b ++ []) in test :: [Bool] 
     59  :: (?a::Bool, ?b::[Bool]) => [Bool] 
    6060}}} 
    6161 
     
    6363 
    6464{{{ 
    65 test.hs:5:8: 
     65test.hs:4:8: 
    6666    Unbound implicit parameter (?a::Bool) 
    6767      arising from a use of implicit parameter `?a' 
    6868    In the first argument of `(:)', namely `?a' 
    69     In the expression: ?a : ?b : [] 
    70     In an equation for `test': test = ?a : ?b : [] 
     69    In the expression: ?a : (?b ++ []) 
     70    In an equation for `test': test = ?a : (?b ++ []) 
    7171 
    72 test.hs:5:13: 
    73     Unbound implicit parameter (?b::Bool) 
     72test.hs:4:14: 
     73    Unbound implicit parameter (?b::[Bool]) 
    7474      arising from a use of implicit parameter `?b' 
    75     In the first argument of `(:)', namely `?b' 
    76     In the second argument of `(:)', namely `?b : []' 
    77     In the expression: ?a : ?b : [] 
     75    In the first argument of `(++)', namely `?b' 
     76    In the second argument of `(:)', namely `(?b ++ [])' 
     77    In the expression: ?a : (?b ++ []) 
    7878Failed, modules loaded: none. 
    7979}}} 
    8080 
    81 This will show you the type, however, it does consider it an error and fails, so there may be other problems you don't get to see because of it. It also will refuse to load and compile the module, so it's impossible to run the parts of it that are finished. So to correctly use it here, the function would have to be written as: 
     81This will show you the type, however, it does consider it an error and fails, so there may be other problems you don't get to see because of it. It also will refuse to load and compile the module, so it's impossible to run the parts of it that are finished. 
     82 
     83The reason is that the hole becomes a part of the type signature, as a constraint. So to correctly use it here, the function would have to be written as: 
    8284 
    8385{{{ 
    84 test :: (?a::Bool, ?b::Bool) => [Bool] 
    85 test = ?a : ?b : [] 
     86test :: (?a::Bool, ?b::[Bool]) => [Bool] 
     87test = ?a : (?b ++ []) 
    8688}}} 
    8789 
    88 This makes it very impractical to use them as holes, as you have to update this yourself to let the typechecker continue. If this wasn't bad enough, implicit parameters propagate upwards: if another function were to call {{{test}}}, it would show the same implicit parameters (and therefore, all of their type signatures have to be updated if you introduce a new hole). Another tricky problem with implicit parameters is that implicit parameters with the same name in different functions are not assumed to be the same parameter (i.e., required to be unifiable), ''except'' if some function has both implicit parameters in its constraints (so calls them both, possibly indirectly). Lastly, it's impossible to run code with unbound implicit parameters, even if the parameters are never actually used. 
     90This makes it very impractical to use them as holes, as all type signatures have to be updated to let the typechecker continue. Not only in the functions that use the implicit parameter itself, but they propagate upwards, just like class constraints: if another function were to call {{{test}}}, it would have the same implicit parameters (and therefore, all of these type signatures would have to be updated when a new hole is added). Another tricky problem with implicit parameters is that implicit parameters with the same name in different functions are not assumed to be the same parameter (i.e., required to be unifiable), ''except'' if some function has both implicit parameters in its constraints. Lastly, it's impossible to run code with unbound implicit parameters, even if the parameters are never actually used. 
    8991 
    9092----