CS 541 Lecture -*- Outline -*- * Module systems in Haskell (Thompson 2.4 and 15) introduction to modules in Haskell ** Motivation: programming in the large controls name space, allows one to group names, avoid "pollution" gives structure to large system allows separate compilation fitting modules into the language allows use of the language to aid programming in the large In Haskell, a program is a collection of modules, one of which is called Main. The meaning of the program is the value of Main.main :: IO t ** semantics Q: How is a module like a record? both map names to values... so meaning of both is an environment Essentially modules allow one to name declarations, so they satisfy the abstraction principle for declarations ** modules in Haskell ------------------------------------------ EXAMPLE MODULE > module Shape (Shape(Rectangle, Ellipse), > Radius, Side, Vertex, > square, circle, area > ) where > > data Shape = Rectangle Side Side > | Ellipse Radiaus Radius > deriving Show > > type Radius = Float > type Side = Float > type Vertex = (Float, Float) > > square s = Rectangle s s > circle r = Ellipse r r > area :: Shape -> Float > area (Rectangle s1 s2) = s1 * s2 > area (Ellipse r1 r2) = pi * r1 * r2 > mars = Ellipse 1 1.093 ------------------------------------------ (modules without headers are implicitly named Main and export only main) Q: What does this export? Q: What is hidden? ** namespace control *** exports ------------------------------------------ HIDING EXPORTING TYPE CONSTRUCTORS Export list of module module Shape ( ) where ^^^ the export list Exporting types: Shape(..) -- exports Shape and all constructors Shape(Rectangle, Ellipse) -- exports Shape and named constructors Shape -- exports Shape, not the constructors ------------------------------------------ Q: If you were designing Haskell, how would you allow exports of class definitions? same options Q: Suppose we want a default if export list is omitted, what should it be? If omitted export everything declared, but not imported stuff Q: Is it better to name the exported names or the hidden ones? the exported ones, think about the errors which is better: - getting an error message for something that was not exported, - or getting nowhere message for something that was accidentally exported? *** imports ------------------------------------------ IMPORTS > import SOEGraphics makes all the names in the given module available ------------------------------------------ ------------------------------------------ DEALING WITH CONFLICTS > import Graphics > import CowboySimulation What if both define "draw"? ------------------------------------------ ... options are: give an error give an error only if the code uses "draw" (Haskell, Java) pick one, perhaps based on type (seems error prone) ------------------------------------------ RESOLVING CONFLICTS import Graphics(openWindow, runGraphics) import Graphics hiding (draw) import qualified Graphics ------------------------------------------ In Java you don't have these choices of selectivly importing or hiding. You only get to use the qualified name. ** higher order In Haskell, modules can export other modules However, in Haskell, modules themselves are not entities in the language, and cannot be passed the functions and returned from functions; they can't be computed. This is different in standard ML, which has a more sophisticated module system.