Typescript and concrete currying of overloded functions - how to?









up vote
0
down vote

favorite












I'm trying to write point free curried function in typescript. And doing so i do find an issue.

Typescript seems to be immediately evaluating type, and, in my understanding, do not allow very well curried function.



Let me illustrate by an example, first with non curried function



const fn = (x: number): string => null

function inline <T, U>(fn: (x: T) => U, src: T): U
function inline <T, U>(fn: (x: T) => U, src: Iterable<T>): Iterable<U>
function inline(fn: (x: any) => any, src: any): any
return null


const iarr = inline (fn, [1, 2]) // <-- string
const iset = inline (fn, new Set([1, 2])) // <-- Iterable<string>


Everything is in place and iarr and iset are correctly typed.



Now let's curry this function:



function pointfree <T, U>(fn: (x: T) => U): (src: T) => U
function pointfree <T, U>(fn: (x: T) => U): (src: Iterable<T>) => Iterable<U>
function pointfree(fn: (x: any) => any)
return (src: any): any => null


const curried = pointfree (fn) // <-- (src: number) => string

const parr = curried ([1, 2]) // <-- string
const pset = curried (new Set ([1, 2]))
// ^^^^^^^^^^^^^^^
// Argument of type 'Set<number>' is not assignable to parameter of
// type 'number'.

// or without caching same error
const pset = pointfree (fn) (new Set([1, 2]))


pset is evaluated as soon as pointfree (fn) is reached and is auto casted to the first type of the overloads which is an array of numbers, even without caching as curried



  • Is they re a way to achieve what i want?

  • Am i doing it wrong or typescript needs to evaluates, and cannot delay evaluation in this scenario ? (it remains a static check and do not need compilation)

  • Is they're a good way of handling this situation?

It's very common in fp to need to partially apply function...
Thanks in advance










share|improve this question

























    up vote
    0
    down vote

    favorite












    I'm trying to write point free curried function in typescript. And doing so i do find an issue.

    Typescript seems to be immediately evaluating type, and, in my understanding, do not allow very well curried function.



    Let me illustrate by an example, first with non curried function



    const fn = (x: number): string => null

    function inline <T, U>(fn: (x: T) => U, src: T): U
    function inline <T, U>(fn: (x: T) => U, src: Iterable<T>): Iterable<U>
    function inline(fn: (x: any) => any, src: any): any
    return null


    const iarr = inline (fn, [1, 2]) // <-- string
    const iset = inline (fn, new Set([1, 2])) // <-- Iterable<string>


    Everything is in place and iarr and iset are correctly typed.



    Now let's curry this function:



    function pointfree <T, U>(fn: (x: T) => U): (src: T) => U
    function pointfree <T, U>(fn: (x: T) => U): (src: Iterable<T>) => Iterable<U>
    function pointfree(fn: (x: any) => any)
    return (src: any): any => null


    const curried = pointfree (fn) // <-- (src: number) => string

    const parr = curried ([1, 2]) // <-- string
    const pset = curried (new Set ([1, 2]))
    // ^^^^^^^^^^^^^^^
    // Argument of type 'Set<number>' is not assignable to parameter of
    // type 'number'.

    // or without caching same error
    const pset = pointfree (fn) (new Set([1, 2]))


    pset is evaluated as soon as pointfree (fn) is reached and is auto casted to the first type of the overloads which is an array of numbers, even without caching as curried



    • Is they re a way to achieve what i want?

    • Am i doing it wrong or typescript needs to evaluates, and cannot delay evaluation in this scenario ? (it remains a static check and do not need compilation)

    • Is they're a good way of handling this situation?

    It's very common in fp to need to partially apply function...
    Thanks in advance










    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I'm trying to write point free curried function in typescript. And doing so i do find an issue.

      Typescript seems to be immediately evaluating type, and, in my understanding, do not allow very well curried function.



      Let me illustrate by an example, first with non curried function



      const fn = (x: number): string => null

      function inline <T, U>(fn: (x: T) => U, src: T): U
      function inline <T, U>(fn: (x: T) => U, src: Iterable<T>): Iterable<U>
      function inline(fn: (x: any) => any, src: any): any
      return null


      const iarr = inline (fn, [1, 2]) // <-- string
      const iset = inline (fn, new Set([1, 2])) // <-- Iterable<string>


      Everything is in place and iarr and iset are correctly typed.



      Now let's curry this function:



      function pointfree <T, U>(fn: (x: T) => U): (src: T) => U
      function pointfree <T, U>(fn: (x: T) => U): (src: Iterable<T>) => Iterable<U>
      function pointfree(fn: (x: any) => any)
      return (src: any): any => null


      const curried = pointfree (fn) // <-- (src: number) => string

      const parr = curried ([1, 2]) // <-- string
      const pset = curried (new Set ([1, 2]))
      // ^^^^^^^^^^^^^^^
      // Argument of type 'Set<number>' is not assignable to parameter of
      // type 'number'.

      // or without caching same error
      const pset = pointfree (fn) (new Set([1, 2]))


      pset is evaluated as soon as pointfree (fn) is reached and is auto casted to the first type of the overloads which is an array of numbers, even without caching as curried



      • Is they re a way to achieve what i want?

      • Am i doing it wrong or typescript needs to evaluates, and cannot delay evaluation in this scenario ? (it remains a static check and do not need compilation)

      • Is they're a good way of handling this situation?

      It's very common in fp to need to partially apply function...
      Thanks in advance










      share|improve this question













      I'm trying to write point free curried function in typescript. And doing so i do find an issue.

      Typescript seems to be immediately evaluating type, and, in my understanding, do not allow very well curried function.



      Let me illustrate by an example, first with non curried function



      const fn = (x: number): string => null

      function inline <T, U>(fn: (x: T) => U, src: T): U
      function inline <T, U>(fn: (x: T) => U, src: Iterable<T>): Iterable<U>
      function inline(fn: (x: any) => any, src: any): any
      return null


      const iarr = inline (fn, [1, 2]) // <-- string
      const iset = inline (fn, new Set([1, 2])) // <-- Iterable<string>


      Everything is in place and iarr and iset are correctly typed.



      Now let's curry this function:



      function pointfree <T, U>(fn: (x: T) => U): (src: T) => U
      function pointfree <T, U>(fn: (x: T) => U): (src: Iterable<T>) => Iterable<U>
      function pointfree(fn: (x: any) => any)
      return (src: any): any => null


      const curried = pointfree (fn) // <-- (src: number) => string

      const parr = curried ([1, 2]) // <-- string
      const pset = curried (new Set ([1, 2]))
      // ^^^^^^^^^^^^^^^
      // Argument of type 'Set<number>' is not assignable to parameter of
      // type 'number'.

      // or without caching same error
      const pset = pointfree (fn) (new Set([1, 2]))


      pset is evaluated as soon as pointfree (fn) is reached and is auto casted to the first type of the overloads which is an array of numbers, even without caching as curried



      • Is they re a way to achieve what i want?

      • Am i doing it wrong or typescript needs to evaluates, and cannot delay evaluation in this scenario ? (it remains a static check and do not need compilation)

      • Is they're a good way of handling this situation?

      It's very common in fp to need to partially apply function...
      Thanks in advance







      typescript






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 9 at 22:40









      zedryas

      116110




      116110






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          Overloads are useful when different parameter types should result in different return types. It's not useful to have two different overload signatures with the same parameter types. That's because, as the handbook says:




          [The compiler] looks at the overload list, and proceeding with the first overload attempts to call the function with the provided parameters. If it finds a match, it picks this overload as the correct overload.




          In your definition of pointfree, the parameter lists are identical for each overload. That means the compiler will always choose the first one if it chooses one at all.



          So, what's the right way to do this? I suggest having a single call signature that returns an overloaded function. Like this:



          // call signature, returns overloaded function
          function pointfree<T, U>(fn: (x: T) => U):
          (src: T): U,
          (src: Iterable<T>): Iterable<U>
          ;
          // implementation signature is the same as before
          function pointfree(fn: (x: any) => any)
          return (src: any): any => null



          Let's use it:



          const curried = pointfree(fn)
          // const curried:
          // (src: number): string;
          // (src: Iterable<number>): Iterable<string>;
          //


          Now you can see that curried is an overloaded function with two call signatures. So the following calls behave as you expect:



          const parr = curried([1, 2]) // <-- string
          const pset = curried(new Set([1, 2])) // <-- Iterable<string>


          Okay, hope that helps. Good luck!






          share|improve this answer




















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53234178%2ftypescript-and-concrete-currying-of-overloded-functions-how-to%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote



            accepted










            Overloads are useful when different parameter types should result in different return types. It's not useful to have two different overload signatures with the same parameter types. That's because, as the handbook says:




            [The compiler] looks at the overload list, and proceeding with the first overload attempts to call the function with the provided parameters. If it finds a match, it picks this overload as the correct overload.




            In your definition of pointfree, the parameter lists are identical for each overload. That means the compiler will always choose the first one if it chooses one at all.



            So, what's the right way to do this? I suggest having a single call signature that returns an overloaded function. Like this:



            // call signature, returns overloaded function
            function pointfree<T, U>(fn: (x: T) => U):
            (src: T): U,
            (src: Iterable<T>): Iterable<U>
            ;
            // implementation signature is the same as before
            function pointfree(fn: (x: any) => any)
            return (src: any): any => null



            Let's use it:



            const curried = pointfree(fn)
            // const curried:
            // (src: number): string;
            // (src: Iterable<number>): Iterable<string>;
            //


            Now you can see that curried is an overloaded function with two call signatures. So the following calls behave as you expect:



            const parr = curried([1, 2]) // <-- string
            const pset = curried(new Set([1, 2])) // <-- Iterable<string>


            Okay, hope that helps. Good luck!






            share|improve this answer
























              up vote
              2
              down vote



              accepted










              Overloads are useful when different parameter types should result in different return types. It's not useful to have two different overload signatures with the same parameter types. That's because, as the handbook says:




              [The compiler] looks at the overload list, and proceeding with the first overload attempts to call the function with the provided parameters. If it finds a match, it picks this overload as the correct overload.




              In your definition of pointfree, the parameter lists are identical for each overload. That means the compiler will always choose the first one if it chooses one at all.



              So, what's the right way to do this? I suggest having a single call signature that returns an overloaded function. Like this:



              // call signature, returns overloaded function
              function pointfree<T, U>(fn: (x: T) => U):
              (src: T): U,
              (src: Iterable<T>): Iterable<U>
              ;
              // implementation signature is the same as before
              function pointfree(fn: (x: any) => any)
              return (src: any): any => null



              Let's use it:



              const curried = pointfree(fn)
              // const curried:
              // (src: number): string;
              // (src: Iterable<number>): Iterable<string>;
              //


              Now you can see that curried is an overloaded function with two call signatures. So the following calls behave as you expect:



              const parr = curried([1, 2]) // <-- string
              const pset = curried(new Set([1, 2])) // <-- Iterable<string>


              Okay, hope that helps. Good luck!






              share|improve this answer






















                up vote
                2
                down vote



                accepted







                up vote
                2
                down vote



                accepted






                Overloads are useful when different parameter types should result in different return types. It's not useful to have two different overload signatures with the same parameter types. That's because, as the handbook says:




                [The compiler] looks at the overload list, and proceeding with the first overload attempts to call the function with the provided parameters. If it finds a match, it picks this overload as the correct overload.




                In your definition of pointfree, the parameter lists are identical for each overload. That means the compiler will always choose the first one if it chooses one at all.



                So, what's the right way to do this? I suggest having a single call signature that returns an overloaded function. Like this:



                // call signature, returns overloaded function
                function pointfree<T, U>(fn: (x: T) => U):
                (src: T): U,
                (src: Iterable<T>): Iterable<U>
                ;
                // implementation signature is the same as before
                function pointfree(fn: (x: any) => any)
                return (src: any): any => null



                Let's use it:



                const curried = pointfree(fn)
                // const curried:
                // (src: number): string;
                // (src: Iterable<number>): Iterable<string>;
                //


                Now you can see that curried is an overloaded function with two call signatures. So the following calls behave as you expect:



                const parr = curried([1, 2]) // <-- string
                const pset = curried(new Set([1, 2])) // <-- Iterable<string>


                Okay, hope that helps. Good luck!






                share|improve this answer












                Overloads are useful when different parameter types should result in different return types. It's not useful to have two different overload signatures with the same parameter types. That's because, as the handbook says:




                [The compiler] looks at the overload list, and proceeding with the first overload attempts to call the function with the provided parameters. If it finds a match, it picks this overload as the correct overload.




                In your definition of pointfree, the parameter lists are identical for each overload. That means the compiler will always choose the first one if it chooses one at all.



                So, what's the right way to do this? I suggest having a single call signature that returns an overloaded function. Like this:



                // call signature, returns overloaded function
                function pointfree<T, U>(fn: (x: T) => U):
                (src: T): U,
                (src: Iterable<T>): Iterable<U>
                ;
                // implementation signature is the same as before
                function pointfree(fn: (x: any) => any)
                return (src: any): any => null



                Let's use it:



                const curried = pointfree(fn)
                // const curried:
                // (src: number): string;
                // (src: Iterable<number>): Iterable<string>;
                //


                Now you can see that curried is an overloaded function with two call signatures. So the following calls behave as you expect:



                const parr = curried([1, 2]) // <-- string
                const pset = curried(new Set([1, 2])) // <-- Iterable<string>


                Okay, hope that helps. Good luck!







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 10 at 0:43









                jcalz

                20.4k21535




                20.4k21535



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53234178%2ftypescript-and-concrete-currying-of-overloded-functions-how-to%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Darth Vader #20

                    How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

                    Ondo