Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I write multiple raku Type smart matches on one line

Tags:

physics

raku

I know that this will not work, since I tried it:

if $r ~~ BearingTrue || CompassAdj || CourseAdj { nextsame };

But - is there a neat, concise and legible way to do multiple Type smart matches on one line rather than have to expand to a given/when or if/else construct?

like image 317
p6steve Avatar asked Jan 15 '21 17:01

p6steve


2 Answers

Have you tried :

if $r ~~ BearingTrue | CompassAdj | CourseAdj { nextsame };

This should give you an Any Junction that with then match OK.

like image 190
Scimon Proctor Avatar answered Jan 04 '23 09:01

Scimon Proctor


This Answer is to let me address the comment from @jubilatious1 a bit more clearly.

I am working on a new raku module, see line 225 ish here Physics::Navigation

For illustrative purposes, the code now looks like this...

class BearingTrue { ...}
class BearingMag  { ...}

sub err-msg { die "Can't mix BearingTrue and BearingMag for add/subtract!" }

class BearingTrue is Bearing is export {

    multi method compass { <T> }                        #get compass

    multi method compass( Str $_ ) {                    #set compass
        die "BearingTrue compass must be <T>" unless $_ eq <T> }

    method M {                                          #coerce to BearingMag
        my $nv = $.value + ( +$variation + +$deviation );
        BearingMag.new( value => $nv, compass => <M> )
    }

    #| can't mix unless BearingMag 
    multi method add( BearingMag ) { err-msg }
    multi method subtract( BearingMag ) { err-msg }
}

So I decided to recast the code to use multi-method add and subtract to check type matches to prevent a lost mariner from adding a magnetic bearing to a true one. I feel that this is cleaner even than Scimon's great answer, since in that instance, my method was accepting all child types of Bearing and then using an if statement to detect a type error.

You are welcome to go...

zef install https://github.com/p6steve/raku-Physics-Navigation.git

then follow the example at the top of bin/synopsis-navigation.raku to use the module and make the various classes available in your own code.

If you are just keen to see how the pieces fit then I suggest writing your own simple classes on similar lines and working through the examples in books such as ThinkRaku chapter 12. I recommend this for the clarity and level of information and it treats inheritance and roles equally.

I am confident that others will feel my code style is over-reliant on inheritance. I feel that since a magnetic-bearing is strictly a derived concept from a bearing-in-general that this is right for my code - but roles and composition is less restrictive and provides similar encapsulation with better maintainability.

like image 22
p6steve Avatar answered Jan 04 '23 10:01

p6steve