How can I convert a Str to an Int only when it represents an integer?

One possible signature would be

Numeric() $ where Int

or, restricting to strings,

Numeric(Str:D) $ where Int

The way Int:D(Any) works in Rakudo is by creating a multi candidate that accepts Any, converts it to an Int, and uses the result to call your original subroutine.

If you instead do that yourself, you can have more control over how it works.

proto sub foo ( Int:D() $n ) {*}

multi sub foo ( Any:D $n ) {
  my $i = try $n.Numeric.narrow;

  if $i ~~ Int:D {

    samewith $i

  } else {

    X::TypeCheck::Binding::Parameter.new(

      # there are more arguments that should be added here
      got => $n,
      expected => Int:D(),

    ).throw

  }
}

multi sub foo ( Int:D $n ) { put "Got <$n> of type {$n.^name}" }

Tags:

Raku

Signature