Creating a Maybe type in Perl 6 Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!How to create a new object instance from a TypeWhat are POD types in C++?What's the canonical way to check for type in Python?How to determine a Python variable's type?What are the differences between type() and isinstance()?How to check if type of a variable is string?Change data type of columns in PandasMaybe types in DWhy does constraining a Perl 6 named parameter to a definite value make it a required value?Are typed signatures for stubbed methods not enforced in roles for Perl6?

Why complex landing gears are used instead of simple,reliability and light weight muscle wire or shape memory alloys?

RSA find public exponent

Central Vacuuming: Is it worth it, and how does it compare to normal vacuuming?

Tannaka duality for semisimple groups

Would color changing eyes affect vision?

Moving a wrapfig vertically to encroach partially on a subsection title

What does it mean that physics no longer uses mechanical models to describe phenomena?

The Nth Gryphon Number

Is CEO the "profession" with the most psychopaths?

I can't produce songs

How to force a browser when connecting to a specific domain to be https only using only the client machine?

Tips to organize LaTeX presentations for a semester

Is there public access to the Meteor Crater in Arizona?

After Sam didn't return home in the end, were he and Al still friends?

A proverb that is used to imply that you have unexpectedly faced a big problem

In musical terms, what properties are varied by the human voice to produce different words / syllables?

Can an iPhone 7 be made to function as a NFC Tag?

Monty Hall Problem-Probability Paradox

Why do early math courses focus on the cross sections of a cone and not on other 3D objects?

Putting class ranking in CV, but against dept guidelines

Why is std::move not [[nodiscard]] in C++20?

Getting out of while loop on console

Trying to understand entropy as a novice in thermodynamics

The test team as an enemy of development? And how can this be avoided?



Creating a Maybe type in Perl 6



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!How to create a new object instance from a TypeWhat are POD types in C++?What's the canonical way to check for type in Python?How to determine a Python variable's type?What are the differences between type() and isinstance()?How to check if type of a variable is string?Change data type of columns in PandasMaybe types in DWhy does constraining a Perl 6 named parameter to a definite value make it a required value?Are typed signatures for stubbed methods not enforced in roles for Perl6?



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








8















I have a lot of functions that can fail, but also have a return type defined in their signature. Since I like defining the types of variables whenever possible, I want to define a Maybe subset to use for this. What I came up with is this:



subset Maybe is export of Mu where Mu | Failure;


The problem with this is Failure is a subclass of Mu, so this will match anything and everything, when what I really want is to be able to match one specific type along with Failure dynamically. My next thought was to create a parameterized role to use as a type, since I don't want to create subsets for every single type that could also be a Failure. I imagine it looking something like this:



role Maybe[::T] 
# ...


sub foo(--> Int) rand < 0.5 ?? 1 !! fail 'oops'

my Maybe[Int] $foo = foo;


Only I have no clue what I'd need to add to the role in order to make this work. Is it possible to create a role like this? If not, is there another way I could create a type to do what I want?










share|improve this question




























    8















    I have a lot of functions that can fail, but also have a return type defined in their signature. Since I like defining the types of variables whenever possible, I want to define a Maybe subset to use for this. What I came up with is this:



    subset Maybe is export of Mu where Mu | Failure;


    The problem with this is Failure is a subclass of Mu, so this will match anything and everything, when what I really want is to be able to match one specific type along with Failure dynamically. My next thought was to create a parameterized role to use as a type, since I don't want to create subsets for every single type that could also be a Failure. I imagine it looking something like this:



    role Maybe[::T] 
    # ...


    sub foo(--> Int) rand < 0.5 ?? 1 !! fail 'oops'

    my Maybe[Int] $foo = foo;


    Only I have no clue what I'd need to add to the role in order to make this work. Is it possible to create a role like this? If not, is there another way I could create a type to do what I want?










    share|improve this question
























      8












      8








      8








      I have a lot of functions that can fail, but also have a return type defined in their signature. Since I like defining the types of variables whenever possible, I want to define a Maybe subset to use for this. What I came up with is this:



      subset Maybe is export of Mu where Mu | Failure;


      The problem with this is Failure is a subclass of Mu, so this will match anything and everything, when what I really want is to be able to match one specific type along with Failure dynamically. My next thought was to create a parameterized role to use as a type, since I don't want to create subsets for every single type that could also be a Failure. I imagine it looking something like this:



      role Maybe[::T] 
      # ...


      sub foo(--> Int) rand < 0.5 ?? 1 !! fail 'oops'

      my Maybe[Int] $foo = foo;


      Only I have no clue what I'd need to add to the role in order to make this work. Is it possible to create a role like this? If not, is there another way I could create a type to do what I want?










      share|improve this question














      I have a lot of functions that can fail, but also have a return type defined in their signature. Since I like defining the types of variables whenever possible, I want to define a Maybe subset to use for this. What I came up with is this:



      subset Maybe is export of Mu where Mu | Failure;


      The problem with this is Failure is a subclass of Mu, so this will match anything and everything, when what I really want is to be able to match one specific type along with Failure dynamically. My next thought was to create a parameterized role to use as a type, since I don't want to create subsets for every single type that could also be a Failure. I imagine it looking something like this:



      role Maybe[::T] 
      # ...


      sub foo(--> Int) rand < 0.5 ?? 1 !! fail 'oops'

      my Maybe[Int] $foo = foo;


      Only I have no clue what I'd need to add to the role in order to make this work. Is it possible to create a role like this? If not, is there another way I could create a type to do what I want?







      types perl6 raku






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 8 at 23:05









      KaiepiKaiepi

      694112




      694112






















          3 Answers
          3






          active

          oldest

          votes


















          9





          +50











          Perl6 types are already Maybe types.



          It's just that Perl6 has typed nulls unlike most other languages with Maybe types.




          This is Maybe[Int] variable:



          my Int $a;
          my Int:_ $a; # more explicit


          This holds a definite Int:



          my Int:D $a = …; # must be assigned because the default is not “definite”


          This holds a null Int:



          my Int:U $a;



          Note that Failure is a subtype of Nil, so even subroutines that have a return type specified can return them.

          (Nil is not like null or nil from other languages.)



          sub foo ( --> Int:D ) Bool.pick ?? 1 !! fail 'oops' 

          my $foo = foo; # $foo contains the failure object


          Nil is really a type of generic soft failure. When assigned to a variable it just resets it to the default.



          my Int $foo = 1;

          $foo = Nil;

          say $foo.perl; # Int




          my Int:D $bar is default(42) = 1;

          $bar = Nil

          say $bar.perl; # 42


          The typical default is the same as the type.



          my Int $foo;

          say $foo.VAR.default.perl; # Int


          A specific soft failure would be to return a type object



          sub foo ( --> Int )
          Bool.pick ?? 1 !! Int



          That is why I said Nil is a “generic” soft failure.




          Generally if you are defining the type of a variable, you want it to be of that type. So your code should complain immediately if it gets something of another type.



          There are better ways to deal with a Failure.



          sub foo(--> Int:D ) rand < 0.5 ?? 1 !! fail 'oops' 

          with foo() -> Int:D $foo
          … # use $foo here
          else -> $fail
          … # use $fail here



          This works because Failure always sees itself as being undefined.



          You can also use that with when



          given foo() 
          when Int:D -> Int:D $foo
          … # use $foo here

          when Failure:D -> Failure:D $fail
          # a DEFINITE Failure value
          # (`DEFINITE` is different than `defined`.)

          default
          … # handle unexpected values (can be removed if not needed)




          Or just the defined-or operator // if you don't care what kind of failure it is.



          my Int:D $foo = foo() // 1;


          You may even want to use that to turn a Failure into a Nil.



          my Int:D $foo is default(42) = foo() // Nil;



          If you really want a maybe-failure subset, I think this should work:



          sub Maybe-Failure ( Any:U ::Type ) Failure


          my constant Maybe-Int = Maybe-Failure(Int);

          # note that the type has to be known at compile-time for this line:
          my Maybe-Int $foo = foo;


          It doesn't currently work though.



          (Note that you should not be dealing with Mu unless you need to specifically deal with the types and values that are outside of the Any type; like Junction and IterationEnd.)



          Something else that should probably also work is:



          my class Maybe-Failure 
          method ^parameterize ( $, Any:U ::Type )
          anon subset :: of Any where Type


          my Maybe-Failure[Int] $foo;


          This seems like it fails for the same reason the other one does.




          Another way would be to create a new type of class like subset.

          That is subset uses a different MOP than the rest of the classes in Perl6.






          share|improve this answer

























          • This is a good explanation of different ways to deal with failures, but I was looking for a way to define a type for what may be a Failure that I could use when assignin the return value of a function that can fail to a variable before handling it properly. That way, my code could be a little more terse

            – Kaiepi
            Mar 9 at 22:43


















          7














          TL;DR See @Kaiepi's own answer for a solution. But every non-native type in P6 is already automatically an enhanced nullable type that's akin to an enhanced Maybe type. So that needs to be discussed too. To help structure my answer I'm going to pretend it's an XY problem even though it isn't.



          Solving Y




          I want to define a Maybe subset to use for this




          See @Kaiepi's answer.



          All non-native P6 types are already akin to Maybe types



          The subset solution is overkill for what wikipedia defines as a Maybe type which boils down to:




          None [or] the original data type




          It turns out that all non-native P6 types are already something akin to an enhanced Maybe type.



          The enhancement is that the (P6 equivalent of a) None knows what original data type it's been paired with:



          my Int $foo;
          say $foo # (Int) -- akin to an (Int) None


          Solving X




          I have a lot of functions that can fail, but also have a return type defined in their signature.




          As you presumably know, unless use fatal; is in effect, P6 deliberately allows routines to return failures even if there's a return type check that doesn't explicitly allow them. (A subset return type check can explicitly reject them.)



          So given that a return type check Foo is automatically turned into something akin to a subset with a where Failure | Foo clause, it's understandable that you thought to accommodate that by creating an matching subset so you could accept the result when assigning to a variable.



          But as is hopefully clear from the earlier discussion, it may be better to make use of the built in aspect of P6's type system that's akin to Maybe types.



          A Nil may be used to indicate what's called a benign failure. So the following works to indicate failure (as you wish to do in some of your routines) and set a receiving variable to a None (or rather the enhanced P6 equivalent of one):



          sub foo (--> Int) Nil 
          my Int $bar = foo;
          say $bar; # (Int)


          So one option is that you replace calls to fail with return Nil (or just Nil).



          One could imagine a pragma (called, say, failsoft) that demotes all Failures to benign failure Nils:



          use failsoft;
          sub foo (--> Int) fail
          my Int $bar = foo;
          say $bar; # (Int)


          Nullable types



          The wikipedia introduction about Maybe types also says:




          A distinct, but related concept ... is called nullable types (often expressed as A?).




          The closest P6 equivalent to the Int? syntax used by some languages to express a nullable Int is simply Int, without the question mark. The following are valid type constraints:



          • Int -- P6 equivalent of a nullable Int or a Maybe Int


          • Int:D -- P6 equivalent of a non-nullable Int or a Just Int


          • Int:U -- P6 equivalent of an Int null or an (Int) None


          (:D and :U are called type smilies for an obvious reason. :))



          Continuing, wikipedia's Nullable types page says:




          In statically-typed languages, a nullable type is [a Maybe] type (in functional programming terms), while in dynamically-typed languages (where values have types, but variables do not), equivalent behavior is provided by having a single null value.




          In P6:



          • Values have types -- but so do variables.


          • P6 types are akin to an enhanced Maybe type (as explained above) or an enhanced nullable type where there are as many Nones or "null" values as there are types instead of having just a single None or null value.


          (So, is P6 a statically typed language or a dynamically typed language? It's actually Beyond static vs dynamic and is instead static and dynamic.)



          Continuing:




          Primitive types such as integers and booleans cannot generally be null, but the corresponding nullable types (nullable integer and nullable boolean, respectively) can also assume the NULL value.




          In P6, all non-native types (like the arbitrary precision Int type) are akin to enhanced Maybe/nullable types.



          In contrast, all native types (like int -- all lowercase) are non-nullable types -- what wikipedia is calling primitive types. They cannot be null or None:



          my int $foo;
          say $foo; # 0
          $foo = int; # Cannot unbox a type object (int) to int


          Finally, returning to the wikipedia Maybe page:




          The core difference between [maybe] types and nullable types is that [maybe] types support nesting (Maybe (Maybe A) ≠ Maybe A), while nullable types do not (A?? = A?).




          P6's built in types don't support nesting in this way without use of subsets. So a P6 type, while akin to an enhanced Maybe type, is really just an enhanced nullable type.






          share|improve this answer

























          • Good point about what I was calling Maybe not actually being Maybe by definition

            – Kaiepi
            Mar 9 at 23:35











          • I think the explanation's better now. With the Solving X section, while I can see how returning Nil would be better than failing in certain cases, for what I was writing when I asked the question it doesn't. I use failure messages to notify users of the program when something goes wrong, and for some routines, I let their exception get thrown in certain places they're used when failing is unacceptable, but not for other places where it'd make more sense to deal with them in other ways.

            – Kaiepi
            Mar 14 at 9:43


















          6














          Brad Gilbert's answer pointed me in the right direction, particularly:




          Another way would be to create a new type of class like subset.
          That is subset uses a different MOP than the rest of the classes in Perl6.




          The solution I came up with is this:



          use nqp;

          class Maybe
          method ^parameterize(Mu:U M, Mu:U T) Failure)



          my Maybe[Int] $foo = 1;
          say $foo; # OUTPUT: 1
          my Maybe[Int] $bar = Failure.new: 2;
          say $bar.exception.message; # OUTPUT: 2
          my Maybe[Int] $baz = 'qux'; # Throws type error





          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%2f55072228%2fcreating-a-maybe-type-in-perl-6%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            9





            +50











            Perl6 types are already Maybe types.



            It's just that Perl6 has typed nulls unlike most other languages with Maybe types.




            This is Maybe[Int] variable:



            my Int $a;
            my Int:_ $a; # more explicit


            This holds a definite Int:



            my Int:D $a = …; # must be assigned because the default is not “definite”


            This holds a null Int:



            my Int:U $a;



            Note that Failure is a subtype of Nil, so even subroutines that have a return type specified can return them.

            (Nil is not like null or nil from other languages.)



            sub foo ( --> Int:D ) Bool.pick ?? 1 !! fail 'oops' 

            my $foo = foo; # $foo contains the failure object


            Nil is really a type of generic soft failure. When assigned to a variable it just resets it to the default.



            my Int $foo = 1;

            $foo = Nil;

            say $foo.perl; # Int




            my Int:D $bar is default(42) = 1;

            $bar = Nil

            say $bar.perl; # 42


            The typical default is the same as the type.



            my Int $foo;

            say $foo.VAR.default.perl; # Int


            A specific soft failure would be to return a type object



            sub foo ( --> Int )
            Bool.pick ?? 1 !! Int



            That is why I said Nil is a “generic” soft failure.




            Generally if you are defining the type of a variable, you want it to be of that type. So your code should complain immediately if it gets something of another type.



            There are better ways to deal with a Failure.



            sub foo(--> Int:D ) rand < 0.5 ?? 1 !! fail 'oops' 

            with foo() -> Int:D $foo
            … # use $foo here
            else -> $fail
            … # use $fail here



            This works because Failure always sees itself as being undefined.



            You can also use that with when



            given foo() 
            when Int:D -> Int:D $foo
            … # use $foo here

            when Failure:D -> Failure:D $fail
            # a DEFINITE Failure value
            # (`DEFINITE` is different than `defined`.)

            default
            … # handle unexpected values (can be removed if not needed)




            Or just the defined-or operator // if you don't care what kind of failure it is.



            my Int:D $foo = foo() // 1;


            You may even want to use that to turn a Failure into a Nil.



            my Int:D $foo is default(42) = foo() // Nil;



            If you really want a maybe-failure subset, I think this should work:



            sub Maybe-Failure ( Any:U ::Type ) Failure


            my constant Maybe-Int = Maybe-Failure(Int);

            # note that the type has to be known at compile-time for this line:
            my Maybe-Int $foo = foo;


            It doesn't currently work though.



            (Note that you should not be dealing with Mu unless you need to specifically deal with the types and values that are outside of the Any type; like Junction and IterationEnd.)



            Something else that should probably also work is:



            my class Maybe-Failure 
            method ^parameterize ( $, Any:U ::Type )
            anon subset :: of Any where Type


            my Maybe-Failure[Int] $foo;


            This seems like it fails for the same reason the other one does.




            Another way would be to create a new type of class like subset.

            That is subset uses a different MOP than the rest of the classes in Perl6.






            share|improve this answer

























            • This is a good explanation of different ways to deal with failures, but I was looking for a way to define a type for what may be a Failure that I could use when assignin the return value of a function that can fail to a variable before handling it properly. That way, my code could be a little more terse

              – Kaiepi
              Mar 9 at 22:43















            9





            +50











            Perl6 types are already Maybe types.



            It's just that Perl6 has typed nulls unlike most other languages with Maybe types.




            This is Maybe[Int] variable:



            my Int $a;
            my Int:_ $a; # more explicit


            This holds a definite Int:



            my Int:D $a = …; # must be assigned because the default is not “definite”


            This holds a null Int:



            my Int:U $a;



            Note that Failure is a subtype of Nil, so even subroutines that have a return type specified can return them.

            (Nil is not like null or nil from other languages.)



            sub foo ( --> Int:D ) Bool.pick ?? 1 !! fail 'oops' 

            my $foo = foo; # $foo contains the failure object


            Nil is really a type of generic soft failure. When assigned to a variable it just resets it to the default.



            my Int $foo = 1;

            $foo = Nil;

            say $foo.perl; # Int




            my Int:D $bar is default(42) = 1;

            $bar = Nil

            say $bar.perl; # 42


            The typical default is the same as the type.



            my Int $foo;

            say $foo.VAR.default.perl; # Int


            A specific soft failure would be to return a type object



            sub foo ( --> Int )
            Bool.pick ?? 1 !! Int



            That is why I said Nil is a “generic” soft failure.




            Generally if you are defining the type of a variable, you want it to be of that type. So your code should complain immediately if it gets something of another type.



            There are better ways to deal with a Failure.



            sub foo(--> Int:D ) rand < 0.5 ?? 1 !! fail 'oops' 

            with foo() -> Int:D $foo
            … # use $foo here
            else -> $fail
            … # use $fail here



            This works because Failure always sees itself as being undefined.



            You can also use that with when



            given foo() 
            when Int:D -> Int:D $foo
            … # use $foo here

            when Failure:D -> Failure:D $fail
            # a DEFINITE Failure value
            # (`DEFINITE` is different than `defined`.)

            default
            … # handle unexpected values (can be removed if not needed)




            Or just the defined-or operator // if you don't care what kind of failure it is.



            my Int:D $foo = foo() // 1;


            You may even want to use that to turn a Failure into a Nil.



            my Int:D $foo is default(42) = foo() // Nil;



            If you really want a maybe-failure subset, I think this should work:



            sub Maybe-Failure ( Any:U ::Type ) Failure


            my constant Maybe-Int = Maybe-Failure(Int);

            # note that the type has to be known at compile-time for this line:
            my Maybe-Int $foo = foo;


            It doesn't currently work though.



            (Note that you should not be dealing with Mu unless you need to specifically deal with the types and values that are outside of the Any type; like Junction and IterationEnd.)



            Something else that should probably also work is:



            my class Maybe-Failure 
            method ^parameterize ( $, Any:U ::Type )
            anon subset :: of Any where Type


            my Maybe-Failure[Int] $foo;


            This seems like it fails for the same reason the other one does.




            Another way would be to create a new type of class like subset.

            That is subset uses a different MOP than the rest of the classes in Perl6.






            share|improve this answer

























            • This is a good explanation of different ways to deal with failures, but I was looking for a way to define a type for what may be a Failure that I could use when assignin the return value of a function that can fail to a variable before handling it properly. That way, my code could be a little more terse

              – Kaiepi
              Mar 9 at 22:43













            9





            +50







            9





            +50



            9




            +50







            Perl6 types are already Maybe types.



            It's just that Perl6 has typed nulls unlike most other languages with Maybe types.




            This is Maybe[Int] variable:



            my Int $a;
            my Int:_ $a; # more explicit


            This holds a definite Int:



            my Int:D $a = …; # must be assigned because the default is not “definite”


            This holds a null Int:



            my Int:U $a;



            Note that Failure is a subtype of Nil, so even subroutines that have a return type specified can return them.

            (Nil is not like null or nil from other languages.)



            sub foo ( --> Int:D ) Bool.pick ?? 1 !! fail 'oops' 

            my $foo = foo; # $foo contains the failure object


            Nil is really a type of generic soft failure. When assigned to a variable it just resets it to the default.



            my Int $foo = 1;

            $foo = Nil;

            say $foo.perl; # Int




            my Int:D $bar is default(42) = 1;

            $bar = Nil

            say $bar.perl; # 42


            The typical default is the same as the type.



            my Int $foo;

            say $foo.VAR.default.perl; # Int


            A specific soft failure would be to return a type object



            sub foo ( --> Int )
            Bool.pick ?? 1 !! Int



            That is why I said Nil is a “generic” soft failure.




            Generally if you are defining the type of a variable, you want it to be of that type. So your code should complain immediately if it gets something of another type.



            There are better ways to deal with a Failure.



            sub foo(--> Int:D ) rand < 0.5 ?? 1 !! fail 'oops' 

            with foo() -> Int:D $foo
            … # use $foo here
            else -> $fail
            … # use $fail here



            This works because Failure always sees itself as being undefined.



            You can also use that with when



            given foo() 
            when Int:D -> Int:D $foo
            … # use $foo here

            when Failure:D -> Failure:D $fail
            # a DEFINITE Failure value
            # (`DEFINITE` is different than `defined`.)

            default
            … # handle unexpected values (can be removed if not needed)




            Or just the defined-or operator // if you don't care what kind of failure it is.



            my Int:D $foo = foo() // 1;


            You may even want to use that to turn a Failure into a Nil.



            my Int:D $foo is default(42) = foo() // Nil;



            If you really want a maybe-failure subset, I think this should work:



            sub Maybe-Failure ( Any:U ::Type ) Failure


            my constant Maybe-Int = Maybe-Failure(Int);

            # note that the type has to be known at compile-time for this line:
            my Maybe-Int $foo = foo;


            It doesn't currently work though.



            (Note that you should not be dealing with Mu unless you need to specifically deal with the types and values that are outside of the Any type; like Junction and IterationEnd.)



            Something else that should probably also work is:



            my class Maybe-Failure 
            method ^parameterize ( $, Any:U ::Type )
            anon subset :: of Any where Type


            my Maybe-Failure[Int] $foo;


            This seems like it fails for the same reason the other one does.




            Another way would be to create a new type of class like subset.

            That is subset uses a different MOP than the rest of the classes in Perl6.






            share|improve this answer

















            Perl6 types are already Maybe types.



            It's just that Perl6 has typed nulls unlike most other languages with Maybe types.




            This is Maybe[Int] variable:



            my Int $a;
            my Int:_ $a; # more explicit


            This holds a definite Int:



            my Int:D $a = …; # must be assigned because the default is not “definite”


            This holds a null Int:



            my Int:U $a;



            Note that Failure is a subtype of Nil, so even subroutines that have a return type specified can return them.

            (Nil is not like null or nil from other languages.)



            sub foo ( --> Int:D ) Bool.pick ?? 1 !! fail 'oops' 

            my $foo = foo; # $foo contains the failure object


            Nil is really a type of generic soft failure. When assigned to a variable it just resets it to the default.



            my Int $foo = 1;

            $foo = Nil;

            say $foo.perl; # Int




            my Int:D $bar is default(42) = 1;

            $bar = Nil

            say $bar.perl; # 42


            The typical default is the same as the type.



            my Int $foo;

            say $foo.VAR.default.perl; # Int


            A specific soft failure would be to return a type object



            sub foo ( --> Int )
            Bool.pick ?? 1 !! Int



            That is why I said Nil is a “generic” soft failure.




            Generally if you are defining the type of a variable, you want it to be of that type. So your code should complain immediately if it gets something of another type.



            There are better ways to deal with a Failure.



            sub foo(--> Int:D ) rand < 0.5 ?? 1 !! fail 'oops' 

            with foo() -> Int:D $foo
            … # use $foo here
            else -> $fail
            … # use $fail here



            This works because Failure always sees itself as being undefined.



            You can also use that with when



            given foo() 
            when Int:D -> Int:D $foo
            … # use $foo here

            when Failure:D -> Failure:D $fail
            # a DEFINITE Failure value
            # (`DEFINITE` is different than `defined`.)

            default
            … # handle unexpected values (can be removed if not needed)




            Or just the defined-or operator // if you don't care what kind of failure it is.



            my Int:D $foo = foo() // 1;


            You may even want to use that to turn a Failure into a Nil.



            my Int:D $foo is default(42) = foo() // Nil;



            If you really want a maybe-failure subset, I think this should work:



            sub Maybe-Failure ( Any:U ::Type ) Failure


            my constant Maybe-Int = Maybe-Failure(Int);

            # note that the type has to be known at compile-time for this line:
            my Maybe-Int $foo = foo;


            It doesn't currently work though.



            (Note that you should not be dealing with Mu unless you need to specifically deal with the types and values that are outside of the Any type; like Junction and IterationEnd.)



            Something else that should probably also work is:



            my class Maybe-Failure 
            method ^parameterize ( $, Any:U ::Type )
            anon subset :: of Any where Type


            my Maybe-Failure[Int] $foo;


            This seems like it fails for the same reason the other one does.




            Another way would be to create a new type of class like subset.

            That is subset uses a different MOP than the rest of the classes in Perl6.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 9 at 22:40









            ugexe

            2,7561529




            2,7561529










            answered Mar 9 at 17:03









            Brad GilbertBrad Gilbert

            26.2k866112




            26.2k866112












            • This is a good explanation of different ways to deal with failures, but I was looking for a way to define a type for what may be a Failure that I could use when assignin the return value of a function that can fail to a variable before handling it properly. That way, my code could be a little more terse

              – Kaiepi
              Mar 9 at 22:43

















            • This is a good explanation of different ways to deal with failures, but I was looking for a way to define a type for what may be a Failure that I could use when assignin the return value of a function that can fail to a variable before handling it properly. That way, my code could be a little more terse

              – Kaiepi
              Mar 9 at 22:43
















            This is a good explanation of different ways to deal with failures, but I was looking for a way to define a type for what may be a Failure that I could use when assignin the return value of a function that can fail to a variable before handling it properly. That way, my code could be a little more terse

            – Kaiepi
            Mar 9 at 22:43





            This is a good explanation of different ways to deal with failures, but I was looking for a way to define a type for what may be a Failure that I could use when assignin the return value of a function that can fail to a variable before handling it properly. That way, my code could be a little more terse

            – Kaiepi
            Mar 9 at 22:43













            7














            TL;DR See @Kaiepi's own answer for a solution. But every non-native type in P6 is already automatically an enhanced nullable type that's akin to an enhanced Maybe type. So that needs to be discussed too. To help structure my answer I'm going to pretend it's an XY problem even though it isn't.



            Solving Y




            I want to define a Maybe subset to use for this




            See @Kaiepi's answer.



            All non-native P6 types are already akin to Maybe types



            The subset solution is overkill for what wikipedia defines as a Maybe type which boils down to:




            None [or] the original data type




            It turns out that all non-native P6 types are already something akin to an enhanced Maybe type.



            The enhancement is that the (P6 equivalent of a) None knows what original data type it's been paired with:



            my Int $foo;
            say $foo # (Int) -- akin to an (Int) None


            Solving X




            I have a lot of functions that can fail, but also have a return type defined in their signature.




            As you presumably know, unless use fatal; is in effect, P6 deliberately allows routines to return failures even if there's a return type check that doesn't explicitly allow them. (A subset return type check can explicitly reject them.)



            So given that a return type check Foo is automatically turned into something akin to a subset with a where Failure | Foo clause, it's understandable that you thought to accommodate that by creating an matching subset so you could accept the result when assigning to a variable.



            But as is hopefully clear from the earlier discussion, it may be better to make use of the built in aspect of P6's type system that's akin to Maybe types.



            A Nil may be used to indicate what's called a benign failure. So the following works to indicate failure (as you wish to do in some of your routines) and set a receiving variable to a None (or rather the enhanced P6 equivalent of one):



            sub foo (--> Int) Nil 
            my Int $bar = foo;
            say $bar; # (Int)


            So one option is that you replace calls to fail with return Nil (or just Nil).



            One could imagine a pragma (called, say, failsoft) that demotes all Failures to benign failure Nils:



            use failsoft;
            sub foo (--> Int) fail
            my Int $bar = foo;
            say $bar; # (Int)


            Nullable types



            The wikipedia introduction about Maybe types also says:




            A distinct, but related concept ... is called nullable types (often expressed as A?).




            The closest P6 equivalent to the Int? syntax used by some languages to express a nullable Int is simply Int, without the question mark. The following are valid type constraints:



            • Int -- P6 equivalent of a nullable Int or a Maybe Int


            • Int:D -- P6 equivalent of a non-nullable Int or a Just Int


            • Int:U -- P6 equivalent of an Int null or an (Int) None


            (:D and :U are called type smilies for an obvious reason. :))



            Continuing, wikipedia's Nullable types page says:




            In statically-typed languages, a nullable type is [a Maybe] type (in functional programming terms), while in dynamically-typed languages (where values have types, but variables do not), equivalent behavior is provided by having a single null value.




            In P6:



            • Values have types -- but so do variables.


            • P6 types are akin to an enhanced Maybe type (as explained above) or an enhanced nullable type where there are as many Nones or "null" values as there are types instead of having just a single None or null value.


            (So, is P6 a statically typed language or a dynamically typed language? It's actually Beyond static vs dynamic and is instead static and dynamic.)



            Continuing:




            Primitive types such as integers and booleans cannot generally be null, but the corresponding nullable types (nullable integer and nullable boolean, respectively) can also assume the NULL value.




            In P6, all non-native types (like the arbitrary precision Int type) are akin to enhanced Maybe/nullable types.



            In contrast, all native types (like int -- all lowercase) are non-nullable types -- what wikipedia is calling primitive types. They cannot be null or None:



            my int $foo;
            say $foo; # 0
            $foo = int; # Cannot unbox a type object (int) to int


            Finally, returning to the wikipedia Maybe page:




            The core difference between [maybe] types and nullable types is that [maybe] types support nesting (Maybe (Maybe A) ≠ Maybe A), while nullable types do not (A?? = A?).




            P6's built in types don't support nesting in this way without use of subsets. So a P6 type, while akin to an enhanced Maybe type, is really just an enhanced nullable type.






            share|improve this answer

























            • Good point about what I was calling Maybe not actually being Maybe by definition

              – Kaiepi
              Mar 9 at 23:35











            • I think the explanation's better now. With the Solving X section, while I can see how returning Nil would be better than failing in certain cases, for what I was writing when I asked the question it doesn't. I use failure messages to notify users of the program when something goes wrong, and for some routines, I let their exception get thrown in certain places they're used when failing is unacceptable, but not for other places where it'd make more sense to deal with them in other ways.

              – Kaiepi
              Mar 14 at 9:43















            7














            TL;DR See @Kaiepi's own answer for a solution. But every non-native type in P6 is already automatically an enhanced nullable type that's akin to an enhanced Maybe type. So that needs to be discussed too. To help structure my answer I'm going to pretend it's an XY problem even though it isn't.



            Solving Y




            I want to define a Maybe subset to use for this




            See @Kaiepi's answer.



            All non-native P6 types are already akin to Maybe types



            The subset solution is overkill for what wikipedia defines as a Maybe type which boils down to:




            None [or] the original data type




            It turns out that all non-native P6 types are already something akin to an enhanced Maybe type.



            The enhancement is that the (P6 equivalent of a) None knows what original data type it's been paired with:



            my Int $foo;
            say $foo # (Int) -- akin to an (Int) None


            Solving X




            I have a lot of functions that can fail, but also have a return type defined in their signature.




            As you presumably know, unless use fatal; is in effect, P6 deliberately allows routines to return failures even if there's a return type check that doesn't explicitly allow them. (A subset return type check can explicitly reject them.)



            So given that a return type check Foo is automatically turned into something akin to a subset with a where Failure | Foo clause, it's understandable that you thought to accommodate that by creating an matching subset so you could accept the result when assigning to a variable.



            But as is hopefully clear from the earlier discussion, it may be better to make use of the built in aspect of P6's type system that's akin to Maybe types.



            A Nil may be used to indicate what's called a benign failure. So the following works to indicate failure (as you wish to do in some of your routines) and set a receiving variable to a None (or rather the enhanced P6 equivalent of one):



            sub foo (--> Int) Nil 
            my Int $bar = foo;
            say $bar; # (Int)


            So one option is that you replace calls to fail with return Nil (or just Nil).



            One could imagine a pragma (called, say, failsoft) that demotes all Failures to benign failure Nils:



            use failsoft;
            sub foo (--> Int) fail
            my Int $bar = foo;
            say $bar; # (Int)


            Nullable types



            The wikipedia introduction about Maybe types also says:




            A distinct, but related concept ... is called nullable types (often expressed as A?).




            The closest P6 equivalent to the Int? syntax used by some languages to express a nullable Int is simply Int, without the question mark. The following are valid type constraints:



            • Int -- P6 equivalent of a nullable Int or a Maybe Int


            • Int:D -- P6 equivalent of a non-nullable Int or a Just Int


            • Int:U -- P6 equivalent of an Int null or an (Int) None


            (:D and :U are called type smilies for an obvious reason. :))



            Continuing, wikipedia's Nullable types page says:




            In statically-typed languages, a nullable type is [a Maybe] type (in functional programming terms), while in dynamically-typed languages (where values have types, but variables do not), equivalent behavior is provided by having a single null value.




            In P6:



            • Values have types -- but so do variables.


            • P6 types are akin to an enhanced Maybe type (as explained above) or an enhanced nullable type where there are as many Nones or "null" values as there are types instead of having just a single None or null value.


            (So, is P6 a statically typed language or a dynamically typed language? It's actually Beyond static vs dynamic and is instead static and dynamic.)



            Continuing:




            Primitive types such as integers and booleans cannot generally be null, but the corresponding nullable types (nullable integer and nullable boolean, respectively) can also assume the NULL value.




            In P6, all non-native types (like the arbitrary precision Int type) are akin to enhanced Maybe/nullable types.



            In contrast, all native types (like int -- all lowercase) are non-nullable types -- what wikipedia is calling primitive types. They cannot be null or None:



            my int $foo;
            say $foo; # 0
            $foo = int; # Cannot unbox a type object (int) to int


            Finally, returning to the wikipedia Maybe page:




            The core difference between [maybe] types and nullable types is that [maybe] types support nesting (Maybe (Maybe A) ≠ Maybe A), while nullable types do not (A?? = A?).




            P6's built in types don't support nesting in this way without use of subsets. So a P6 type, while akin to an enhanced Maybe type, is really just an enhanced nullable type.






            share|improve this answer

























            • Good point about what I was calling Maybe not actually being Maybe by definition

              – Kaiepi
              Mar 9 at 23:35











            • I think the explanation's better now. With the Solving X section, while I can see how returning Nil would be better than failing in certain cases, for what I was writing when I asked the question it doesn't. I use failure messages to notify users of the program when something goes wrong, and for some routines, I let their exception get thrown in certain places they're used when failing is unacceptable, but not for other places where it'd make more sense to deal with them in other ways.

              – Kaiepi
              Mar 14 at 9:43













            7












            7








            7







            TL;DR See @Kaiepi's own answer for a solution. But every non-native type in P6 is already automatically an enhanced nullable type that's akin to an enhanced Maybe type. So that needs to be discussed too. To help structure my answer I'm going to pretend it's an XY problem even though it isn't.



            Solving Y




            I want to define a Maybe subset to use for this




            See @Kaiepi's answer.



            All non-native P6 types are already akin to Maybe types



            The subset solution is overkill for what wikipedia defines as a Maybe type which boils down to:




            None [or] the original data type




            It turns out that all non-native P6 types are already something akin to an enhanced Maybe type.



            The enhancement is that the (P6 equivalent of a) None knows what original data type it's been paired with:



            my Int $foo;
            say $foo # (Int) -- akin to an (Int) None


            Solving X




            I have a lot of functions that can fail, but also have a return type defined in their signature.




            As you presumably know, unless use fatal; is in effect, P6 deliberately allows routines to return failures even if there's a return type check that doesn't explicitly allow them. (A subset return type check can explicitly reject them.)



            So given that a return type check Foo is automatically turned into something akin to a subset with a where Failure | Foo clause, it's understandable that you thought to accommodate that by creating an matching subset so you could accept the result when assigning to a variable.



            But as is hopefully clear from the earlier discussion, it may be better to make use of the built in aspect of P6's type system that's akin to Maybe types.



            A Nil may be used to indicate what's called a benign failure. So the following works to indicate failure (as you wish to do in some of your routines) and set a receiving variable to a None (or rather the enhanced P6 equivalent of one):



            sub foo (--> Int) Nil 
            my Int $bar = foo;
            say $bar; # (Int)


            So one option is that you replace calls to fail with return Nil (or just Nil).



            One could imagine a pragma (called, say, failsoft) that demotes all Failures to benign failure Nils:



            use failsoft;
            sub foo (--> Int) fail
            my Int $bar = foo;
            say $bar; # (Int)


            Nullable types



            The wikipedia introduction about Maybe types also says:




            A distinct, but related concept ... is called nullable types (often expressed as A?).




            The closest P6 equivalent to the Int? syntax used by some languages to express a nullable Int is simply Int, without the question mark. The following are valid type constraints:



            • Int -- P6 equivalent of a nullable Int or a Maybe Int


            • Int:D -- P6 equivalent of a non-nullable Int or a Just Int


            • Int:U -- P6 equivalent of an Int null or an (Int) None


            (:D and :U are called type smilies for an obvious reason. :))



            Continuing, wikipedia's Nullable types page says:




            In statically-typed languages, a nullable type is [a Maybe] type (in functional programming terms), while in dynamically-typed languages (where values have types, but variables do not), equivalent behavior is provided by having a single null value.




            In P6:



            • Values have types -- but so do variables.


            • P6 types are akin to an enhanced Maybe type (as explained above) or an enhanced nullable type where there are as many Nones or "null" values as there are types instead of having just a single None or null value.


            (So, is P6 a statically typed language or a dynamically typed language? It's actually Beyond static vs dynamic and is instead static and dynamic.)



            Continuing:




            Primitive types such as integers and booleans cannot generally be null, but the corresponding nullable types (nullable integer and nullable boolean, respectively) can also assume the NULL value.




            In P6, all non-native types (like the arbitrary precision Int type) are akin to enhanced Maybe/nullable types.



            In contrast, all native types (like int -- all lowercase) are non-nullable types -- what wikipedia is calling primitive types. They cannot be null or None:



            my int $foo;
            say $foo; # 0
            $foo = int; # Cannot unbox a type object (int) to int


            Finally, returning to the wikipedia Maybe page:




            The core difference between [maybe] types and nullable types is that [maybe] types support nesting (Maybe (Maybe A) ≠ Maybe A), while nullable types do not (A?? = A?).




            P6's built in types don't support nesting in this way without use of subsets. So a P6 type, while akin to an enhanced Maybe type, is really just an enhanced nullable type.






            share|improve this answer















            TL;DR See @Kaiepi's own answer for a solution. But every non-native type in P6 is already automatically an enhanced nullable type that's akin to an enhanced Maybe type. So that needs to be discussed too. To help structure my answer I'm going to pretend it's an XY problem even though it isn't.



            Solving Y




            I want to define a Maybe subset to use for this




            See @Kaiepi's answer.



            All non-native P6 types are already akin to Maybe types



            The subset solution is overkill for what wikipedia defines as a Maybe type which boils down to:




            None [or] the original data type




            It turns out that all non-native P6 types are already something akin to an enhanced Maybe type.



            The enhancement is that the (P6 equivalent of a) None knows what original data type it's been paired with:



            my Int $foo;
            say $foo # (Int) -- akin to an (Int) None


            Solving X




            I have a lot of functions that can fail, but also have a return type defined in their signature.




            As you presumably know, unless use fatal; is in effect, P6 deliberately allows routines to return failures even if there's a return type check that doesn't explicitly allow them. (A subset return type check can explicitly reject them.)



            So given that a return type check Foo is automatically turned into something akin to a subset with a where Failure | Foo clause, it's understandable that you thought to accommodate that by creating an matching subset so you could accept the result when assigning to a variable.



            But as is hopefully clear from the earlier discussion, it may be better to make use of the built in aspect of P6's type system that's akin to Maybe types.



            A Nil may be used to indicate what's called a benign failure. So the following works to indicate failure (as you wish to do in some of your routines) and set a receiving variable to a None (or rather the enhanced P6 equivalent of one):



            sub foo (--> Int) Nil 
            my Int $bar = foo;
            say $bar; # (Int)


            So one option is that you replace calls to fail with return Nil (or just Nil).



            One could imagine a pragma (called, say, failsoft) that demotes all Failures to benign failure Nils:



            use failsoft;
            sub foo (--> Int) fail
            my Int $bar = foo;
            say $bar; # (Int)


            Nullable types



            The wikipedia introduction about Maybe types also says:




            A distinct, but related concept ... is called nullable types (often expressed as A?).




            The closest P6 equivalent to the Int? syntax used by some languages to express a nullable Int is simply Int, without the question mark. The following are valid type constraints:



            • Int -- P6 equivalent of a nullable Int or a Maybe Int


            • Int:D -- P6 equivalent of a non-nullable Int or a Just Int


            • Int:U -- P6 equivalent of an Int null or an (Int) None


            (:D and :U are called type smilies for an obvious reason. :))



            Continuing, wikipedia's Nullable types page says:




            In statically-typed languages, a nullable type is [a Maybe] type (in functional programming terms), while in dynamically-typed languages (where values have types, but variables do not), equivalent behavior is provided by having a single null value.




            In P6:



            • Values have types -- but so do variables.


            • P6 types are akin to an enhanced Maybe type (as explained above) or an enhanced nullable type where there are as many Nones or "null" values as there are types instead of having just a single None or null value.


            (So, is P6 a statically typed language or a dynamically typed language? It's actually Beyond static vs dynamic and is instead static and dynamic.)



            Continuing:




            Primitive types such as integers and booleans cannot generally be null, but the corresponding nullable types (nullable integer and nullable boolean, respectively) can also assume the NULL value.




            In P6, all non-native types (like the arbitrary precision Int type) are akin to enhanced Maybe/nullable types.



            In contrast, all native types (like int -- all lowercase) are non-nullable types -- what wikipedia is calling primitive types. They cannot be null or None:



            my int $foo;
            say $foo; # 0
            $foo = int; # Cannot unbox a type object (int) to int


            Finally, returning to the wikipedia Maybe page:




            The core difference between [maybe] types and nullable types is that [maybe] types support nesting (Maybe (Maybe A) ≠ Maybe A), while nullable types do not (A?? = A?).




            P6's built in types don't support nesting in this way without use of subsets. So a P6 type, while akin to an enhanced Maybe type, is really just an enhanced nullable type.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 11 at 22:35

























            answered Mar 9 at 22:45









            raiphraiph

            12.3k22444




            12.3k22444












            • Good point about what I was calling Maybe not actually being Maybe by definition

              – Kaiepi
              Mar 9 at 23:35











            • I think the explanation's better now. With the Solving X section, while I can see how returning Nil would be better than failing in certain cases, for what I was writing when I asked the question it doesn't. I use failure messages to notify users of the program when something goes wrong, and for some routines, I let their exception get thrown in certain places they're used when failing is unacceptable, but not for other places where it'd make more sense to deal with them in other ways.

              – Kaiepi
              Mar 14 at 9:43

















            • Good point about what I was calling Maybe not actually being Maybe by definition

              – Kaiepi
              Mar 9 at 23:35











            • I think the explanation's better now. With the Solving X section, while I can see how returning Nil would be better than failing in certain cases, for what I was writing when I asked the question it doesn't. I use failure messages to notify users of the program when something goes wrong, and for some routines, I let their exception get thrown in certain places they're used when failing is unacceptable, but not for other places where it'd make more sense to deal with them in other ways.

              – Kaiepi
              Mar 14 at 9:43
















            Good point about what I was calling Maybe not actually being Maybe by definition

            – Kaiepi
            Mar 9 at 23:35





            Good point about what I was calling Maybe not actually being Maybe by definition

            – Kaiepi
            Mar 9 at 23:35













            I think the explanation's better now. With the Solving X section, while I can see how returning Nil would be better than failing in certain cases, for what I was writing when I asked the question it doesn't. I use failure messages to notify users of the program when something goes wrong, and for some routines, I let their exception get thrown in certain places they're used when failing is unacceptable, but not for other places where it'd make more sense to deal with them in other ways.

            – Kaiepi
            Mar 14 at 9:43





            I think the explanation's better now. With the Solving X section, while I can see how returning Nil would be better than failing in certain cases, for what I was writing when I asked the question it doesn't. I use failure messages to notify users of the program when something goes wrong, and for some routines, I let their exception get thrown in certain places they're used when failing is unacceptable, but not for other places where it'd make more sense to deal with them in other ways.

            – Kaiepi
            Mar 14 at 9:43











            6














            Brad Gilbert's answer pointed me in the right direction, particularly:




            Another way would be to create a new type of class like subset.
            That is subset uses a different MOP than the rest of the classes in Perl6.




            The solution I came up with is this:



            use nqp;

            class Maybe
            method ^parameterize(Mu:U M, Mu:U T) Failure)



            my Maybe[Int] $foo = 1;
            say $foo; # OUTPUT: 1
            my Maybe[Int] $bar = Failure.new: 2;
            say $bar.exception.message; # OUTPUT: 2
            my Maybe[Int] $baz = 'qux'; # Throws type error





            share|improve this answer



























              6














              Brad Gilbert's answer pointed me in the right direction, particularly:




              Another way would be to create a new type of class like subset.
              That is subset uses a different MOP than the rest of the classes in Perl6.




              The solution I came up with is this:



              use nqp;

              class Maybe
              method ^parameterize(Mu:U M, Mu:U T) Failure)



              my Maybe[Int] $foo = 1;
              say $foo; # OUTPUT: 1
              my Maybe[Int] $bar = Failure.new: 2;
              say $bar.exception.message; # OUTPUT: 2
              my Maybe[Int] $baz = 'qux'; # Throws type error





              share|improve this answer

























                6












                6








                6







                Brad Gilbert's answer pointed me in the right direction, particularly:




                Another way would be to create a new type of class like subset.
                That is subset uses a different MOP than the rest of the classes in Perl6.




                The solution I came up with is this:



                use nqp;

                class Maybe
                method ^parameterize(Mu:U M, Mu:U T) Failure)



                my Maybe[Int] $foo = 1;
                say $foo; # OUTPUT: 1
                my Maybe[Int] $bar = Failure.new: 2;
                say $bar.exception.message; # OUTPUT: 2
                my Maybe[Int] $baz = 'qux'; # Throws type error





                share|improve this answer













                Brad Gilbert's answer pointed me in the right direction, particularly:




                Another way would be to create a new type of class like subset.
                That is subset uses a different MOP than the rest of the classes in Perl6.




                The solution I came up with is this:



                use nqp;

                class Maybe
                method ^parameterize(Mu:U M, Mu:U T) Failure)



                my Maybe[Int] $foo = 1;
                say $foo; # OUTPUT: 1
                my Maybe[Int] $bar = Failure.new: 2;
                say $bar.exception.message; # OUTPUT: 2
                my Maybe[Int] $baz = 'qux'; # Throws type error






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 9 at 22:30









                KaiepiKaiepi

                694112




                694112



























                    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%2f55072228%2fcreating-a-maybe-type-in-perl-6%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

                    AWS Lex not identifying response if by a variable The 2019 Stack Overflow Developer Survey Results Are In Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) The Ask Question Wizard is Live! Data science time! April 2019 and salary with experienceEnforcing custom enumeration in AWS LEX for slot valuesHow to give response based on user response in Amazon Lex?Intercepting AWS Lambda Response to a AWS Lex QueryLex chat bot error: Reached second execution of fulfillment lambda on the same utteranceamazon lex showing invalid responseLambda response send back to Lex slot?Response card in Amazon lexAmazon Lex - Lambda response return HTML to botHow can I solve 424 (Failed Dependency) (python) obtained from Amazon lex?

                    Алба-Юлія

                    Захаров Федір Захарович