@IIvana про java - это не динамический язык и там нету downcast-инга, т.е. cast сверху вниз вообще запрещен и компилятор сильно ругается на это и стат анализаторы. Есть стандартный subtyping. Так же есть костыль сбоку - reflection, который позволяет извращаться, как угодно делать downcast, создавать новые объекты и все что можно с точностью до type erasure, который очень сильно сужает возможности.
Считается плохим тоном и используется разве что для тестов, дебага или в каком-нить AOP.
В Haskell есть возможности получить то же, что и без reflection через typeable; аналога reflection который будет смотреть infotable и генерировать новые типы и т.п. вроде нету, ghc-heap-view самое близкое.
Но самое главное, java не дает возможность полноценно работать с произвольным объектом, т.е. максимум что ты можешь сделать это проверить тип и попробовать скастануть к конкретному, а вселенная типов открытая.
В динамических же языках множество типов закрытое и всегда можно сделать полный поиск и анализ, чтобы ни пришло. Что является огромными плюсом в repl-driven программировании, и так скажем "открытых системах", так что люди могут модифицировать систему прямо на ходу. Я не уверен, что этот паттерн прям всегда нужен, но там такие языки на коне.