Changes between Version 14 and Version 15 of Records/TypePunningDeclaredOverloadedRecordFields


Ignore:
Timestamp:
Mar 28, 2012 1:47:22 AM (3 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.