1. No, since your root tag is sealed, it can represent the presented hierarchy as ADT:
data Sql = Statement Statement | Where Where -- ^ This is the *type* called `Statement` -- ^ This is the *constructor* called `Statement` data Statement = Union Statement Statement | Select Where data Where = And Where Where | Or Where Where | Equals
In this case, it is possible because you can list all the "subclasses" of your data type ( Sql in this case), which allows you to convert them to ADT constructors. Emulating type hierarchies as ADTs is difficult only if you want the user to add "constructors" / "subclasses" arbitrarily by the user.
2. The term ADT is never applicable to Scala code, since Scala lacks ADT in this language. However, the classes you introduced behave similarly to ADT, so I would say "close enough."
3 and 4. Languages have different strengths and weaknesses.
Haskell can emulate every function of the Scala language, and Scala can emulate every function of the Haskell, since both languages are complete and allow different levels of metaprogramming to be used. Of course, Haskell has a Template Haskell that allows you to emulate something, maybe you can use TH to write Scala code in a Haskell file and compile it as Haskell.
Objects and inheritance are not needed in Haskell, and ADT is mostly not needed in Scala, so there is no reason to compare them. Most object-oriented functions can also be emulated with simple classes like Haskell and data types and using module boundaries. ADT can be emulated in Scala with case classes, and classes of type Haskell can be emulated with implicit parameters and implicit object instances.
However, I would say that in general it is easiest to emulate some Scala functions in Haskell, because Haskell allows for more "implicit language extensions" than Scala. I mean, if you want to emulate Haskell Monad in Scala, you need to write a lot of code in parts that use Monad s, whereas if you want to emulate, say, Scala limited continuations or implicit parameters in Haskell, you can simply write a Monad instance (to continue) or a class with several parameters (for implicit parameters) once for this and the code that you later write in your actual functions will look very close to the Scala code without a large boiler plate. Many, if not most, of the advanced Scala features also come from Haskell or OCaml, so they already exist and don't need to be translated.
In other words: the complex code needed to add a new function needs to be added in only one place in Haskell, after which it can be easily used in several places, while you often have to add a lot of “noise”, everywhere in your Scala code if you want to emulate the Haskell function.