Похоже, вы немного запутались в существовании. То, что вы написали
data Poly f = (Foo f) => Poly { member :: f }
, определяет семейство типов, например, один тип Poly One
, другой тип Poly Two
и т. д. При построении Poly
проверяется его Foo
-нессность.
Проблема с
makePoly :: Bool -> Poly f
заключается в том, что вызывающий может выбрать f
. Так что
makePoly True :: Poly One
makePoly True :: Poly Two
makePoly True :: Poly Elephant
все должны работать, но ваша функция не работает таким образом. Похоже, вы почти знаете, что делаете, так как если бы вместо определения семейства типов вы определили единственный экзистенциальный тип, то это было бы хорошо:
data Poly = forall f. (Foo f) => Poly { member :: f }
Обратите внимание что слева от знака =
нет f
, так что это один тип, а не семейство. Поэтому функция, утверждающая, что она возвращает Poly
, может вернуть любой Poly
, который ей нравится. Это определение заставляет ваш код работать.
Техническое примечание, средство доступа к полю member
совершенно бесполезно, поскольку тип возвращаемого значения зависит от того, какое значение передается в
member :: Poly -> ????
, поэтому ему нельзя присвоить тип в система типов Haskell (хотя системы с зависимыми типами могут это делать). Чтобы использовать Poly
, вы должны соответствовать шаблону:
usePoly :: Poly -> Int
usePoly (Poly x) = whoAmI x -- x :: a for some *unknown* type a in this scope
Другое примечание, Poly
полностью эквивалентно Int
, так как если нам дан Poly x
, все, что мы знаем о x
, это то, что это Foo
, и единственное, что мы можем сделать с Foo
, это call whoAmI
. В таких случаях я бы просто пропустил экзистенциальный и использовал Int
. Но существуют действительные варианты использования экзистенциалов, они гораздо реже, чем ожидают люди.
if (objectReference instanceof type){
//Your code goes here
}
Можно только использовать instanceof
с литералом класса: это:
Class type = String.class;
if (myObj instanceof String) // will compile
if (myObj instanceof type) //will not compile
Альтернатива должна использовать метод Class.isInstance
if (type.isInstance(myObj)) // will compile
obj instanceof TargetType
возвращает true на всякий случай TargetType
находится в иерархии типа, которая содержит obj
.