Does it support concepts like separation of declaration and implementation (interfaces and classes in Java)?
How about restricting access (like access modifiers in J
How do you separate declaration and implementation in Haskell?
In Haskell you can define a typeclass, which is rather different from an object oriented class so don't let the name fool you. Using the keyword class, you can declare function names and type signatures which can be instantiated (implemented) elsewhere for a particular data type.
For example, the Hashable typeclass defines the hash function, which can turn any instantiated data type into an Int. Have a new, funky data type you want to be able to hash? Fine, make an instance of Hashable. The most common data types are instantiated by the module that defines Hashable (see the linked documentation for 'Instances').
Typeclasses aren't the only way to define an interface. A method that is often under-rated is a plain old data structure. Because Haskell has first class functions, you can define a data structure that has functions as fields:
data ShuttleInterface =
SI { launch :: Delay -> IO Handle
, deploy :: Payload -> IO ()
, getStatus :: IO Status
}
And your functions can build or consume this data structure:
deployAllSensors :: ShuttleInterface -> IO ()
deployAllSensors shuttle = do
status <- getStatus shuttle
let notDeployed = filter (not . deployed) (sensors status)
when (isOrbiting status) (mapM_ deploySensor notDeployed)
-- we used the well-known Haskell functions: filter, not, , when, mapM_
-- and some supporting functions were assumed:
isOrbitting :: Status -> Bool
deploySensor :: Sensor -> IO ()
sensors :: Status -> [Sensor]
deployed :: Sensor -> Bool
How do you restrict access to data in Haskell?
To provide abstraction, Haskell uses Algebraic Data Types. To protect fields developers declare a data type but don't export it's constructors - instead they only export a set of safe primitives that maintain desired invariants.
For example, the Map module provides a balanced tree. It couldn't guarantee balance if anyone could just declare a Map using the primitives of Branch and Leaf, so the makers didn't export those. Construction of a map must rely on what is exported from Data.Map (and those have access to/use the constructors by virtue of being in the same module) such as fromList, empty, singleton, and a whole bunch of modifiers.