In Swift, can you create a protocol which requires a particular function only when certain conditions hold about the associated types?Usage of protocols as array types and function parameters in swiftWhat does “Protocol … can only be used as a generic constraint because it has Self or associated type requirements” mean?Protocol func returning SelfIn Swift, how can I declare a variable of a specific type that conforms to one or more protocols?Swift cast self in class funcSwift: Generic ProtocolsDefine a Swift protocol which requires a specific type of sequenceHow to list Swift types that conform to protocol using reflection?implement protocol with different associated typeIs it possible in Swift to require an associated type to conform to an associated protocol of an associated type?

Make Gimbap cutter

NUL delimited variable

Should I put programming books I wrote a few years ago on my resume?

Is it okay to have a sequel start immediately after the end of the first book?

Converting from CMYK to RGB (to work with it), then back to CMYK

ASCII Meme Arrow Generator

Ability To Change Root User Password (Vulnerability?)

What should I discuss with my DM prior to my first game?

If there's something that implicates the president why is there then a national security issue? (John Dowd)

Why is the length of the Kelvin unit of temperature equal to that of the Celsius unit?

Should I refuse to be named as co-author of a low quality paper?

Why isn't Bash trap working if output is redirected to stdout?

Print "N NE E SE S SW W NW"

Why do radiation hardened IC packages often have long leads?

How and why do references in academic papers work?

Zig-zag function - coded solution

Does the new finding on "reversing a quantum jump mid-flight" rule out any interpretations of QM?

Can you make an identity from this product?

Do empty drive bays need to be filled?

What is the Leave No Trace way to dispose of coffee grounds?

Can the removal of a duty-free sales trolley result in a measurable reduction in emissions?

Increase speed altering column on large table to NON NULL

Housemarks (superimposed & combined letters, heraldry)

Is the Keras Embedding layer dependent on the target label?



In Swift, can you create a protocol which requires a particular function only when certain conditions hold about the associated types?


Usage of protocols as array types and function parameters in swiftWhat does “Protocol … can only be used as a generic constraint because it has Self or associated type requirements” mean?Protocol func returning SelfIn Swift, how can I declare a variable of a specific type that conforms to one or more protocols?Swift cast self in class funcSwift: Generic ProtocolsDefine a Swift protocol which requires a specific type of sequenceHow to list Swift types that conform to protocol using reflection?implement protocol with different associated typeIs it possible in Swift to require an associated type to conform to an associated protocol of an associated type?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















I would like to express a Swift protocol similar to the following two snippets which both fail to compile.



Attempt 1:



protocol AbstractFunction 
associatedtype Domain
associatedtype Codomain

func apply(_ x: Domain) -> Codomain

static var identity: Self where Domain == Codomain get



Attempt 2:



protocol AbstractFunction 
associatedtype Domain
associatedtype Codomain

func apply(_ x: Domain) -> Codomain

static func identity() -> Self where Domain == Codomain get



The first is not even valid within the Swift grammar while the second fails with
'where' clause cannot be attached to a non-generic declaration.



Both of these examples try to express a protocol which describes functions which are not instances of an actual function type (A) -> B. If one has types Vector2 and Vector3, one could imagine creating types Matrix2x2, Matrix2x3, and Matrix3x3 and conforming them to the AbstractFunction protocol. The domain of MatrixNxM would be VectorM and the codomain would be VectorN. Square matrices have an identity matrix, but the concept of an identity matrix (or really identity function) does not make sense when the domain and codomain differ.



Consequently, I would like the protocol AbstractFunction to require conforming types to provide an identity, but only in the case where Domain == Codomain. Is this possible?










share|improve this question




























    0















    I would like to express a Swift protocol similar to the following two snippets which both fail to compile.



    Attempt 1:



    protocol AbstractFunction 
    associatedtype Domain
    associatedtype Codomain

    func apply(_ x: Domain) -> Codomain

    static var identity: Self where Domain == Codomain get



    Attempt 2:



    protocol AbstractFunction 
    associatedtype Domain
    associatedtype Codomain

    func apply(_ x: Domain) -> Codomain

    static func identity() -> Self where Domain == Codomain get



    The first is not even valid within the Swift grammar while the second fails with
    'where' clause cannot be attached to a non-generic declaration.



    Both of these examples try to express a protocol which describes functions which are not instances of an actual function type (A) -> B. If one has types Vector2 and Vector3, one could imagine creating types Matrix2x2, Matrix2x3, and Matrix3x3 and conforming them to the AbstractFunction protocol. The domain of MatrixNxM would be VectorM and the codomain would be VectorN. Square matrices have an identity matrix, but the concept of an identity matrix (or really identity function) does not make sense when the domain and codomain differ.



    Consequently, I would like the protocol AbstractFunction to require conforming types to provide an identity, but only in the case where Domain == Codomain. Is this possible?










    share|improve this question
























      0












      0








      0








      I would like to express a Swift protocol similar to the following two snippets which both fail to compile.



      Attempt 1:



      protocol AbstractFunction 
      associatedtype Domain
      associatedtype Codomain

      func apply(_ x: Domain) -> Codomain

      static var identity: Self where Domain == Codomain get



      Attempt 2:



      protocol AbstractFunction 
      associatedtype Domain
      associatedtype Codomain

      func apply(_ x: Domain) -> Codomain

      static func identity() -> Self where Domain == Codomain get



      The first is not even valid within the Swift grammar while the second fails with
      'where' clause cannot be attached to a non-generic declaration.



      Both of these examples try to express a protocol which describes functions which are not instances of an actual function type (A) -> B. If one has types Vector2 and Vector3, one could imagine creating types Matrix2x2, Matrix2x3, and Matrix3x3 and conforming them to the AbstractFunction protocol. The domain of MatrixNxM would be VectorM and the codomain would be VectorN. Square matrices have an identity matrix, but the concept of an identity matrix (or really identity function) does not make sense when the domain and codomain differ.



      Consequently, I would like the protocol AbstractFunction to require conforming types to provide an identity, but only in the case where Domain == Codomain. Is this possible?










      share|improve this question














      I would like to express a Swift protocol similar to the following two snippets which both fail to compile.



      Attempt 1:



      protocol AbstractFunction 
      associatedtype Domain
      associatedtype Codomain

      func apply(_ x: Domain) -> Codomain

      static var identity: Self where Domain == Codomain get



      Attempt 2:



      protocol AbstractFunction 
      associatedtype Domain
      associatedtype Codomain

      func apply(_ x: Domain) -> Codomain

      static func identity() -> Self where Domain == Codomain get



      The first is not even valid within the Swift grammar while the second fails with
      'where' clause cannot be attached to a non-generic declaration.



      Both of these examples try to express a protocol which describes functions which are not instances of an actual function type (A) -> B. If one has types Vector2 and Vector3, one could imagine creating types Matrix2x2, Matrix2x3, and Matrix3x3 and conforming them to the AbstractFunction protocol. The domain of MatrixNxM would be VectorM and the codomain would be VectorN. Square matrices have an identity matrix, but the concept of an identity matrix (or really identity function) does not make sense when the domain and codomain differ.



      Consequently, I would like the protocol AbstractFunction to require conforming types to provide an identity, but only in the case where Domain == Codomain. Is this possible?







      swift swift-protocols associated-types






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 24 at 21:56









      deaton.dgdeaton.dg

      388




      388






















          2 Answers
          2






          active

          oldest

          votes


















          1














          You can achieve it by declaring second more strict protocol as:



          protocol AbstractFunction 
          associatedtype Domain
          associatedtype Codomain

          func apply(_ x: Domain) -> Codomain


          protocol AbstractEndofunction: AbstractFunction where Codomain == Domain
          static var identity: Self get



          Example on Int -> Int function:



          final class IntFunction: AbstractEndofunction 
          typealias Domain = Int

          static var identity = IntFunction $0

          private let function: (Int) -> Int

          init(_ function: @escaping (Int) -> Int)
          self.function = function


          func apply(_ x: Int) -> Int
          return function(x)







          share|improve this answer























          • This isn't exactly what I want, but it's close. In my code, I have a struct FreeVectorSpace<T> and another struct FreeLinearMap<T,S> which is a wrapper for a function (T) -> FreeVectorSpace<S>. I would love to make FreeLinearMap<T,S> conform to just one protocol to cover both usages, but this enables me to use extension FreeLinearMap: AbstractEndofunction where T == S, which is pretty close.

            – deaton.dg
            Mar 25 at 0:01


















          0














          I don't think you can do that. However, I can see two another ways that might help you out.



          By using optional type to identity you indicate that a certain type that implements AbstractFunction may or may not have an identity. For instance:



          final class ConcreteFunctionWithoutIdentity: AbstractFunction 
          typealias Domain = Int
          typealias Codomain = Int

          func apply(_ x: Int) -> Int
          return 0


          static var identity: ConcreteFunctionWithoutIdentity?


          // Using
          if let identity = ConcreteFunctionWithoutIdentity.identity else
          // It will not fall here, since ConcreteFunctionWithoutIdentity doesn't have identity
          ...


          final class ConcreteFunctionWithIdentity: AbstractFunction
          typealias Domain = Int
          typealias Codomain = Int

          func apply(_ x: Int) -> Int
          return 0


          static var identity: ConcreteFunctionWithtIdentity?
          // return something



          if let identity = ConcreteFunctionWithtIdentity.identity else
          // It will fall here, since ConcreteFunctionWithIdentity indeed have identity
          ...






          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',
            autoActivateHeartbeat: false,
            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%2f55328952%2fin-swift-can-you-create-a-protocol-which-requires-a-particular-function-only-wh%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            You can achieve it by declaring second more strict protocol as:



            protocol AbstractFunction 
            associatedtype Domain
            associatedtype Codomain

            func apply(_ x: Domain) -> Codomain


            protocol AbstractEndofunction: AbstractFunction where Codomain == Domain
            static var identity: Self get



            Example on Int -> Int function:



            final class IntFunction: AbstractEndofunction 
            typealias Domain = Int

            static var identity = IntFunction $0

            private let function: (Int) -> Int

            init(_ function: @escaping (Int) -> Int)
            self.function = function


            func apply(_ x: Int) -> Int
            return function(x)







            share|improve this answer























            • This isn't exactly what I want, but it's close. In my code, I have a struct FreeVectorSpace<T> and another struct FreeLinearMap<T,S> which is a wrapper for a function (T) -> FreeVectorSpace<S>. I would love to make FreeLinearMap<T,S> conform to just one protocol to cover both usages, but this enables me to use extension FreeLinearMap: AbstractEndofunction where T == S, which is pretty close.

              – deaton.dg
              Mar 25 at 0:01















            1














            You can achieve it by declaring second more strict protocol as:



            protocol AbstractFunction 
            associatedtype Domain
            associatedtype Codomain

            func apply(_ x: Domain) -> Codomain


            protocol AbstractEndofunction: AbstractFunction where Codomain == Domain
            static var identity: Self get



            Example on Int -> Int function:



            final class IntFunction: AbstractEndofunction 
            typealias Domain = Int

            static var identity = IntFunction $0

            private let function: (Int) -> Int

            init(_ function: @escaping (Int) -> Int)
            self.function = function


            func apply(_ x: Int) -> Int
            return function(x)







            share|improve this answer























            • This isn't exactly what I want, but it's close. In my code, I have a struct FreeVectorSpace<T> and another struct FreeLinearMap<T,S> which is a wrapper for a function (T) -> FreeVectorSpace<S>. I would love to make FreeLinearMap<T,S> conform to just one protocol to cover both usages, but this enables me to use extension FreeLinearMap: AbstractEndofunction where T == S, which is pretty close.

              – deaton.dg
              Mar 25 at 0:01













            1












            1








            1







            You can achieve it by declaring second more strict protocol as:



            protocol AbstractFunction 
            associatedtype Domain
            associatedtype Codomain

            func apply(_ x: Domain) -> Codomain


            protocol AbstractEndofunction: AbstractFunction where Codomain == Domain
            static var identity: Self get



            Example on Int -> Int function:



            final class IntFunction: AbstractEndofunction 
            typealias Domain = Int

            static var identity = IntFunction $0

            private let function: (Int) -> Int

            init(_ function: @escaping (Int) -> Int)
            self.function = function


            func apply(_ x: Int) -> Int
            return function(x)







            share|improve this answer













            You can achieve it by declaring second more strict protocol as:



            protocol AbstractFunction 
            associatedtype Domain
            associatedtype Codomain

            func apply(_ x: Domain) -> Codomain


            protocol AbstractEndofunction: AbstractFunction where Codomain == Domain
            static var identity: Self get



            Example on Int -> Int function:



            final class IntFunction: AbstractEndofunction 
            typealias Domain = Int

            static var identity = IntFunction $0

            private let function: (Int) -> Int

            init(_ function: @escaping (Int) -> Int)
            self.function = function


            func apply(_ x: Int) -> Int
            return function(x)








            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 24 at 22:57









            ManWithBearManWithBear

            1,869720




            1,869720












            • This isn't exactly what I want, but it's close. In my code, I have a struct FreeVectorSpace<T> and another struct FreeLinearMap<T,S> which is a wrapper for a function (T) -> FreeVectorSpace<S>. I would love to make FreeLinearMap<T,S> conform to just one protocol to cover both usages, but this enables me to use extension FreeLinearMap: AbstractEndofunction where T == S, which is pretty close.

              – deaton.dg
              Mar 25 at 0:01

















            • This isn't exactly what I want, but it's close. In my code, I have a struct FreeVectorSpace<T> and another struct FreeLinearMap<T,S> which is a wrapper for a function (T) -> FreeVectorSpace<S>. I would love to make FreeLinearMap<T,S> conform to just one protocol to cover both usages, but this enables me to use extension FreeLinearMap: AbstractEndofunction where T == S, which is pretty close.

              – deaton.dg
              Mar 25 at 0:01
















            This isn't exactly what I want, but it's close. In my code, I have a struct FreeVectorSpace<T> and another struct FreeLinearMap<T,S> which is a wrapper for a function (T) -> FreeVectorSpace<S>. I would love to make FreeLinearMap<T,S> conform to just one protocol to cover both usages, but this enables me to use extension FreeLinearMap: AbstractEndofunction where T == S, which is pretty close.

            – deaton.dg
            Mar 25 at 0:01





            This isn't exactly what I want, but it's close. In my code, I have a struct FreeVectorSpace<T> and another struct FreeLinearMap<T,S> which is a wrapper for a function (T) -> FreeVectorSpace<S>. I would love to make FreeLinearMap<T,S> conform to just one protocol to cover both usages, but this enables me to use extension FreeLinearMap: AbstractEndofunction where T == S, which is pretty close.

            – deaton.dg
            Mar 25 at 0:01













            0














            I don't think you can do that. However, I can see two another ways that might help you out.



            By using optional type to identity you indicate that a certain type that implements AbstractFunction may or may not have an identity. For instance:



            final class ConcreteFunctionWithoutIdentity: AbstractFunction 
            typealias Domain = Int
            typealias Codomain = Int

            func apply(_ x: Int) -> Int
            return 0


            static var identity: ConcreteFunctionWithoutIdentity?


            // Using
            if let identity = ConcreteFunctionWithoutIdentity.identity else
            // It will not fall here, since ConcreteFunctionWithoutIdentity doesn't have identity
            ...


            final class ConcreteFunctionWithIdentity: AbstractFunction
            typealias Domain = Int
            typealias Codomain = Int

            func apply(_ x: Int) -> Int
            return 0


            static var identity: ConcreteFunctionWithtIdentity?
            // return something



            if let identity = ConcreteFunctionWithtIdentity.identity else
            // It will fall here, since ConcreteFunctionWithIdentity indeed have identity
            ...






            share|improve this answer



























              0














              I don't think you can do that. However, I can see two another ways that might help you out.



              By using optional type to identity you indicate that a certain type that implements AbstractFunction may or may not have an identity. For instance:



              final class ConcreteFunctionWithoutIdentity: AbstractFunction 
              typealias Domain = Int
              typealias Codomain = Int

              func apply(_ x: Int) -> Int
              return 0


              static var identity: ConcreteFunctionWithoutIdentity?


              // Using
              if let identity = ConcreteFunctionWithoutIdentity.identity else
              // It will not fall here, since ConcreteFunctionWithoutIdentity doesn't have identity
              ...


              final class ConcreteFunctionWithIdentity: AbstractFunction
              typealias Domain = Int
              typealias Codomain = Int

              func apply(_ x: Int) -> Int
              return 0


              static var identity: ConcreteFunctionWithtIdentity?
              // return something



              if let identity = ConcreteFunctionWithtIdentity.identity else
              // It will fall here, since ConcreteFunctionWithIdentity indeed have identity
              ...






              share|improve this answer

























                0












                0








                0







                I don't think you can do that. However, I can see two another ways that might help you out.



                By using optional type to identity you indicate that a certain type that implements AbstractFunction may or may not have an identity. For instance:



                final class ConcreteFunctionWithoutIdentity: AbstractFunction 
                typealias Domain = Int
                typealias Codomain = Int

                func apply(_ x: Int) -> Int
                return 0


                static var identity: ConcreteFunctionWithoutIdentity?


                // Using
                if let identity = ConcreteFunctionWithoutIdentity.identity else
                // It will not fall here, since ConcreteFunctionWithoutIdentity doesn't have identity
                ...


                final class ConcreteFunctionWithIdentity: AbstractFunction
                typealias Domain = Int
                typealias Codomain = Int

                func apply(_ x: Int) -> Int
                return 0


                static var identity: ConcreteFunctionWithtIdentity?
                // return something



                if let identity = ConcreteFunctionWithtIdentity.identity else
                // It will fall here, since ConcreteFunctionWithIdentity indeed have identity
                ...






                share|improve this answer













                I don't think you can do that. However, I can see two another ways that might help you out.



                By using optional type to identity you indicate that a certain type that implements AbstractFunction may or may not have an identity. For instance:



                final class ConcreteFunctionWithoutIdentity: AbstractFunction 
                typealias Domain = Int
                typealias Codomain = Int

                func apply(_ x: Int) -> Int
                return 0


                static var identity: ConcreteFunctionWithoutIdentity?


                // Using
                if let identity = ConcreteFunctionWithoutIdentity.identity else
                // It will not fall here, since ConcreteFunctionWithoutIdentity doesn't have identity
                ...


                final class ConcreteFunctionWithIdentity: AbstractFunction
                typealias Domain = Int
                typealias Codomain = Int

                func apply(_ x: Int) -> Int
                return 0


                static var identity: ConcreteFunctionWithtIdentity?
                // return something



                if let identity = ConcreteFunctionWithtIdentity.identity else
                // It will fall here, since ConcreteFunctionWithIdentity indeed have identity
                ...







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 24 at 22:18









                paivaalanpaivaalan

                1,49211122




                1,49211122



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55328952%2fin-swift-can-you-create-a-protocol-which-requires-a-particular-function-only-wh%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

                    Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                    Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                    Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript