From FP in Scala, chapter 3:
One might object that algebraic data types violate encapsulation by making public the internal representation of a type. In FP, we approach concerns about encapsulation differently—we don’t typically have delicate mutable state which could lead to bugs or violation of invariants if exposed publicly. Exposing the data constructors of a type is often fine, and the decision to do so is approached much like any other decision about what the public API of a data type should be.
We do typically use ADTs for cases where the set of cases is closed (known to be fixed). For List and Tree, changing the set of data constructors would significantly change what these data types are. List is a singly linked list—that is its nature—and the two cases Nil and Cons form part of its useful public API. You can certainly write code that deals with a more abstract API than List (you’ll see examples of this later in the book), but this sort of information hiding can be handled as a separate layer rather than being baked into List directly.