Веб-сайт Perl 6 по функциям говорит
Типы принуждения могут помочь вам иметь определенный тип внутри процедуры, но принимать более широкий ввод. Когда вызывается процедура, аргумент автоматически преобразуется в более узкий тип.
sub double(Int(Cool) $x) { 2 * $x } say double '21'; # 42 say double Any; # Type check failed in binding $x; expected 'Cool' but got 'Any'
Здесь Int - это целевой тип, к которому будет принудительно применяться аргумент, а Cool - тип, который процедура принимает в качестве входа.
Но какая точка для суб? Разве не $x
просто a Int
? Почему вы ограничиваете вызывающего объекта реализацией Cool
для аргумента?
Я в два раза смущен примером, потому что Int
уже is Cool
. Поэтому я сделал пример, когда типы не разделяют иерархию:
class Foo { method foomethod { say 'foomethod' } }
class Bar {}
class Quux is Foo {
# class Quux { # compile error
method Bar { Bar.new }
}
sub foo(Bar(Foo) $c) {
say $c.WHAT; # (Bar)
# $c.foomethod # fails if uncommented: Method 'foomethod' not found for invocant of class 'Bar'
}
foo(Quux.new)
Здесь invocant foo
ограничен, чтобы предоставить foo
, который может быть преобразован в Bar
, но foo
не может даже вызвать метод foo
на $c
, потому что его тип Bar
. Итак, почему бы foo
ухаживать за тем, чтобы тип, который был бы в принудительном состоянии, был foo
в первую очередь?
Может ли кто-нибудь пролить свет на это? Также приветствуются ссылки на соответствующую документацию и части спецификации. Я не мог найти там ничего полезного.