Difference between revisions of "DDC/FieldProjections"

From HaskellWiki
< DDC
Jump to navigation Jump to search
Line 13: Line 13:
   
 
== Custom projections ==
 
== Custom projections ==
We can also define our own, custom projections and use <hask>(.)</hask> to select them. A <hask>project</hask> definition is similar to a regular <hask>instance</hask> definition in that it defines a set of functions associated with a particular type (in this case, <hask>Vector</hask>).
+
We can also define our own, custom projections and use <hask>(.)</hask> to select them. A <hask>project</hask> definition is similar to a regular <hask>instance</hask> definition in that it defines a set of functions associated with a particular type (in this case, <hask>Vector</hask>). When we use <hask>(.)</hask>, its first argument is passed as the first argument to our projection function - and so on.
   
 
<haskell>
 
<haskell>
Line 32: Line 32:
   
 
== Projections are type directed ==
 
== Projections are type directed ==
In Disciple we can re-use the same field names in multiple data types, with different field types. The type system uses the type of the first argument to <hask>(.)</hask> to determine what projection to use. Alternatively, we can use the <hask>(&)</hask> operator to specify the projection type manually.
+
In Disciple we can re-use the same field names in multiple data types, each with different field types. The type system uses the type of the first argument to <hask>(.)</hask> to determine what projection function to use. Alternatively, we can use the <hask>(&)</hask> operator to specify the projection type manually.
   
 
<haskell>
 
<haskell>
Line 45: Line 45:
 
out $ magnitude&{Vector} vec -- prints '5.0'
 
out $ magnitude&{Vector} vec -- prints '5.0'
 
</haskell>
 
</haskell>
  +
  +
Using <hask>(&)</hask>, we can also use "projection" functions who's first argument is not <hask>Vector</hask>.
  +
  +
<haskell>
  +
project Vector where
  +
...
  +
new :: Float -> Float -> Vector
  +
new posX posY = Vector posX posY
  +
  +
main ()
  +
= do ...
  +
vec2 = new&{Vector} 5.0 6.0
  +
<haskell></haskell>

Revision as of 00:09, 19 March 2008

Data fields

When data types are defined using field names, we can use the projection operator (.) to select the fields.

data Vector
         = Vector { x :: Float; y :: Float; }

main ()
 = do   vec = Vector 3.0 4.0
        out vec.x          -- prints '3.0'
        out vec.y          -- prints '4.0'

Custom projections

We can also define our own, custom projections and use (.) to select them. A project definition is similar to a regular instance definition in that it defines a set of functions associated with a particular type (in this case, Vector). When we use (.), its first argument is passed as the first argument to our projection function - and so on.

project Vector where
        magnitude :: Vector -> Float
        magnitude (Vector x y) 
         = sqrt (x * x + y * y)

        dot :: Vector -> Vector -> Float
        dot (Vector x1 y1) (Vector x2 y2)
         = x1 * x2 + y1 * y2

main ()
 = do   ...
        out vec.magnitude               -- prints '5.0'
        out vec.dot (Vector 5.0 6.0)    -- prints '39.0'

Projections are type directed

In Disciple we can re-use the same field names in multiple data types, each with different field types. The type system uses the type of the first argument to (.) to determine what projection function to use. Alternatively, we can use the (&) operator to specify the projection type manually.

data Location 
        = Location { x :: String; y :: String; }

main ()
 = do   ...
        loc = Location "over" "there"
        out loc.x                      -- prints 'over'

        out $ magnitude&{Vector} vec   -- prints '5.0'

Using (&), we can also use "projection" functions who's first argument is not Vector.

project Vector where
        ...
        new :: Float -> Float -> Vector
        new posX posY = Vector posX posY

main ()
 = do   ...
        vec2  = new&{Vector} 5.0 6.0
<haskell>