Веб-сайт 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 в первую очередь?
Может ли кто-нибудь пролить свет на это? Также приветствуются ссылки на соответствующую документацию и части спецификации. Я не мог найти там ничего полезного.