I have an object with options that corresponds to the following record type:
const AwsRegionsEnum = $.EnumType(
  'AWS/Regions',
  'http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html',
  [
    'us-east-1',
    'us-east-2',
    'us-west-1',
    'us-west-2',
    'ca-central-1',
    'eu-west-1',
    'eu-central-1',
    'eu-west-2',
    'ap-northeast-1',
    'ap-northeast-2',
    'ap-southeast-1',
    'ap-southeast-2',
    'ap-south-1',
    'sa-east-1',
  ]
);
const Credentials = $.RecordType({
  accessKeyId: $.String,
  secretAccessKey: $.String,
  region: AwsRegionsEnum,
});
const PullOpts = $.RecordType({
  waitTimeSeconds: S.MaybeType($.Number),
  maxNumberOfMessages: S.MaybeType($.Number),
  credentials: Credentials,
});
And I want to create a function that picks options from such records like R.pick from ramda library. But I want to type list fields for picking. That list can contain only fields that are valid for record of type PullOpts.
Expected behavior for the function:
// pickOpts :: List(<some_type_for_validate_options>) -> PullOpts -> <constructed_type_for_return>
const pickOpts = (pickingOpts, allOpts) => {};
Summary:
How I can write type my function arguments correct (
<some_type_for_validate_options>and<constructed_type_for_return>)?How I can write body of the function using sanctuary function compositions?
Thanks for any help:)
                        
In Sanctuary, it is usually not necessary to pick certain fields from a record. Consider this module:
What is the implementation that should appear in place of the
???. The answer may be surprising: we simply returnuser. This is because every member of theUsertype is also a member of theMinimalUsertype. A record is permitted to contain additional fields. This makes it possible to define functions with types such asid :: { id :: UUID } -> UUIDwhich are not restricted to a particular type (User,Invoice, or whatever).So,
toMinimalUsermay be unnecessary. Since every member of theUsertype is also a member of theMinimalUsertype, we can pass aUser/MinimalUserto a function which expects aMinimalUser.Although the type system won't require us to “strip” fields, we may wish to do so for privacy reasons. Consider
toJson :: User -> String. If we're constructing an API response from aUservalue we may which to exclude theemailfield for privacy reasons. In this case I would suggest this implementation:This is more verbose than the
R.pickequivalent, but that's a price we must pay to deal with records in a more disciplined manner than is required by JavaScript.I can imagine us one day adding a function such as this to Sanctuary:
I can't imagine, though, a similar function operating on arbitrary records as we'd be forced to use a loose type such as
Set String -> Object -> Object. When dealing with records in Sanctuary I prefer to write code which is slightly more verbose but provides stronger guarantees.