-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Composability
Potentially a Semigroupoid instance:
Semigroupoid
class Semigroupoid a where
A
Semigroupoid
is similar to aCategory
but does not require an identity elementidentity
, just composable morphisms.
Semigroupoid
s must satisfy the following law:
- Associativity:
p <<< (q <<< r) = (p <<< q) <<< r
One example of a
Semigroupoid
is the function type constructor(->)
, with(<<<)
defined as function composition.Members
compose :: forall d c b. a c d -> a b c -> a b d
If it will be possible to create arbitrary Scaler
s (#50), then chaining them may become a problem. Consider an application containing a certain area that should be treated as a cartesian graph:
canvas
⇄drawing
drawing
⇄graph
Going between canvas
and graph
requires two conversions:
(graphCoords *~> drawing) *~> canvas
I believe that the scaling functions should be composable, so that this would be equivalent:
graphToCanvas = drawing >>> canvas
graphCoords *~> graphToCanvas
Problem
A Semigroupoid instance would require Scaler
to have a newtype
or data
definition, and type parameters for the from and to types. Something like:
import Gesso.Geometry (Scaler, Canvas, Drawing, mkScaler)
data Graph
graphToDrawing :: Scaler Graph Drawing
graphToDrawing = _.b $ mkScaler graphRect drawing.rect
-- assuming `scalers` is in context
graphToCanvas :: Scaler Graph Canvas
graphToCanvas = graphToDrawing >>> scalers.canvas
But the convenience fields would become less convenient, e.g.:
graphRect = getX drawingToGraph
-- or:
_.x $ unwrap $ drawingToGraph
Alternative
Composition doesn't necessarily require Semigroupoid. Nothing prevents this:
compose :: Scaler -> Scaler -> Scaler
compose aToB bToC = bToC
{ scaling
{ all = aToB.all >>> bToC.all
, x = aToB.x >>> bToC.x
, y = aToB.y >>> bToC.y
, length = aToB.length >>> bToC.length
}
}
Associativity
Alternately, or in addition, the scaling operators could be changed from infix
to infixr
or infixl
.
(graphCoords *~> drawing) *~> canvas -- fine
graphCoords *~> (drawing *~> canvas) -- not fine
canvas <~* (drawing <~* graphCoords) -- fine
(canvas <~* drawing) <~* graphCoords -- not fine
canvas <~* graphCoords *~> drawing -- definitely not fine
Metadata
Metadata
Assignees
Labels
Projects
Status