Skip to content

Higher order functions lose type parameters #417

Description

When making higher order functions that return functions, type parameters are not preserved in return type. Notice in the following example how identityM has the generic type parameter A changed into {}, resulting in a loss of type safety in the rest of the code.

Ideally identityM would have the type <A>(a: A) => A. If this isn't possible, issuing a compiler warning (or error) about loss of genericity would be very helpful in tracking down errors like this.

function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
function identity<A>(a: A): A { return a; }
var identityM = mirror(identity); // type: (a: {}) => {}

var x = 1;
var y = identity(x); // type: number
var z = identityM(x); // type: {}

Activity

  1. wavebeem commented on Aug 10, 2014

    @wavebeem
    Author

    Might be related to #360?

    Also, thanks Basarat Ali Syed (@basarat) for simplifying the example code I wrote to demonstrate this problem.

  2. basarat commented on Aug 10, 2014

    @basarat
    Contributor

    👍

  3. danquirk commented on Aug 11, 2014

    @danquirk
    Member

    Gonna go with dupe of #360.

  4. wavebeem commented on Aug 12, 2014

    @wavebeem
    Author

    Marking this as a duplicate of #360 seems to imply to me that we're going down this route:

    If this isn't possible, issuing a compiler warning (or error) about loss of genericity would be very helpful in tracking down errors like this.

    Please correct me if I'm wrong with that assumption.

    As stated previously:

    Ideally identityM would have the type <A>(a: A) => A.

    Is this feasible?

    Is the problem here that <A>(a: A) => A isn't a type per se?

  5. DanielRosenwasser commented on Aug 12, 2014

    @DanielRosenwasser
    Member

    Is the problem here that (a: A) => A isn't a type per se?

    Actually, the issue is that we instantiate all type parameters at call-site - they are not curried. While not a duplicate per se, what you are seeing (lack of available candidates to instantiate A) is a result of #360, and it certainly seems like there is are people who would like to be notified when this occurs.

    Edit: I previously answered "yes" to your question - I misunderstood and have amended my comment.

  6. danquirk commented on Aug 12, 2014

    @danquirk
    Member

    Basically what I meant was that if we can make generics better at representing certain type patterns we'll certainly do that but our current design is what it is for good reasons (some of which Daniel just described) and we're generally aware of a number of shortcomings that result from the current design. Given that, #360 captures what's the most likely near term result here. I didn't want to leave this open and say 'feel free to propose a new algorithm for generic type inference' since that's not exactly a small task and we've certainly spent a lot of time on it ourselves and ended up with this design. That said, if you do have or end up having a proposed design for how to fix generics in this respect feel free to log a new issue with the details :)

  7. wavebeem commented on Aug 12, 2014

    @wavebeem
    Author

    I don't underestimate the work put in to solving this problem, I was just trying to better understand it. If I have a moment of divine inspiration, I'll be sure to file said issue :-]

  8. fdecampredon commented on Nov 24, 2014

    @fdecampredon

    flowtype actually capture types, would it not be possible to inspire from their algorithm ?

  9. mhegazy commented on May 18, 2017

    @mhegazy
    Contributor

    Tracked by #9366

  10. locked and limited conversation to collaborators on Jun 18, 2018
  11. ahejlsberg commented on Mar 8, 2019

    @ahejlsberg
    Member

    Fixed in #30215.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already createdFixedA PR has been merged for this issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions