DDC/FieldProjections: Difference between revisions
< DDC
No edit summary |
No edit summary |
||
Line 17: | Line 17: | ||
<haskell> | <haskell> | ||
project Vector where | project Vector where | ||
magnitude :: Vector -> Float | |||
magnitude (Vector x y) | magnitude (Vector x y) | ||
= sqrt (x * x + y * y) | = sqrt (x * x + y * y) | ||
dot :: Vector -> Vector -> Float | |||
dot (Vector x1 y1) (Vector x2 y2) | dot (Vector x1 y1) (Vector x2 y2) | ||
= x1 * x2 + y1 * y2 | = x1 * x2 + y1 * y2 |
Revision as of 23:58, 18 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
).
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, with different field types. The type system uses the type of the first argument to (.)
to determine what projection 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'