Changes between Version 14 and Version 15 of Records/TypePunningDeclaredOverloadedRecordFields


Ignore:
Timestamp:
Mar 28, 2012 1:47:22 AM (2 years ago)
Author:
AntC
Comment:

towards type-indexed rows?

Legend:

Unmodified
Added
Removed
Modified
  • Records/TypePunningDeclaredOverloadedRecordFields

    v14 v15  
    1717In case of 'unintended' clash (another module using the same name 'by accident'), usual H98 controls apply to protect encapsulation and representation hiding. 
    1818 
    19 This proposal introduces several new elements of syntax (including some shorthands), all of which desugar to use well-established extensions of ghc. The approach is yet to be prototyped, but I expect that to be possible in ghc v 7.2.1. In particular: 
     19This proposal introduces several new elements of syntax (including some shorthands), all of which desugar to use well-established extensions of ghc. The key type-inference elelemnts of this approach have been tested in ghc v7.2.1. A full prototype is yet to be developed. In particular: 
    2020 * The field name overloading is implemented through usual class and instance mechanisms. 
    2121 * Field selectors are ordinary functions named for the field (but overloaded rather than H98's monomorphic), so field selection is regular function application. (There is no need for syntactically-based disambiguation at point of use.) 
     
    153153 * Now we can now apply the wrapped function polymorphically (after unwrapping within the user code). 
    154154 
    155 '''Parametric polymoprhic fields''' (including changing the parametric record type) 
     155'''Parametric polymorphic fields''' (including changing the parametric record type) 
    156156{{{ 
    157157 -- data ParamR a = ParamR { paramA :: a }                              -- _not_ sharing, so would generate: 
     
    164164 
    165165    instance Has (ParamR a) (ParamA _a)        where                    -- Note: different type args 
    166         get ParamR{ paramA = ParamA x } = x                             -- unwrap the value from the newtype 
     166        get ParamR{ paramA = ParamA x } _ = x                           -- unwrap the value from the newtype 
    167167        set (ParamA x) ParamR{ .. }     = ParamR{ paramA = ParamA x, .. } 
    168168 
     
    172172}}} 
    173173 
     174'''Wilder thought: towards type-indexed rows?''' 
     175 
     176Since we're using the field's type pun to instance the field, perhaps we could avoid the dummy argument to `get`, like this, with a few adjustments for the parametric type: 
     177{{{ 
     178    class Has r t                                           where 
     179        get :: (GetResult r t ~ t) => r -> t                            -- GetResult 'improves' get's result 
     180        set :: t -> r -> SetResult r t                                  --  
     181 
     182    paramA :: ParamR a -> a                                             -- generated selector unwraps the param type, 
     183    paramA r = let (ParamA x) = get r in x                              -- get returns the wrapped newtype 
     184 
     185    instance Has (ParamR a) (ParamA _a)        where                    -- Note: different type args 
     186        get ParamR{ paramA } = paramA                                   -- don't unwrap the value from the newtype 
     187        set (ParamA x) ParamR{ .. }     = ParamR{ paramA = ParamA x, .. } 
     188}}} 
     189 
     190`get`'s result type is effectively 'pulling' the field out of the record. This is getting close to the style of polymorphic/anonymous type-indexed rows, as described in some of the record calculi proposals (such as HList). 
     191 
    174192.