Skip to content

Commit

Permalink
use op
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffreyrosenbluth committed Jan 3, 2014
1 parent eb772ad commit 4f56513
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions src/Diagrams/Core/Trace.hs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,15 @@ import Diagrams.Core.V
-- SortedList -------------------------------------------------
------------------------------------------------------------

-- | A trace returns a sorted list of intersections with the object in
-- increasing order of distanct from the point to the object. We maintain
-- the invariant the the list is sorted in increasing order.
newtype SortedList a = SortedList [a]

instance Wrapped [a] [a] (SortedList a) (SortedList a)
where wrapped = iso SortedList $ \(SortedList x) -> x

-- | SortedLists form a semigroup with merge as composition.
instance Ord a => Semigroup (SortedList a) where
sl0 <> sl1 = SortedList $ merge (view unwrapped sl0) (view unwrapped sl1)
where
Expand Down Expand Up @@ -166,7 +170,7 @@ instance (Ord (Scalar v), VectorSpace v) => Traced (Point v) where
getTrace = const mempty

instance Traced t => Traced (TransInv t) where
getTrace = getTrace . view unwrapped
getTrace = getTrace . op TransInv

instance (Traced a, Traced b, V a ~ V b) => Traced (a,b) where
getTrace (x,y) = getTrace x <> getTrace y
Expand All @@ -188,7 +192,7 @@ instance (Traced b) => Traced (S.Set b) where
-- given object in either the given direction or the opposite direction.
-- Return @Nothing@ if there is no intersection.
traceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)
traceV p v a = case view unwrapped $ ((getTrace a)^.unwrapping Trace) p v of
traceV p v a = case op SortedList $ op Trace (getTrace a) p v of
(s:_) -> Just (s *^ v)
[] -> Nothing

Expand All @@ -213,15 +217,15 @@ maxTraceP p v a = (p .+^) <$> maxTraceV p v a
-- positive traces.
getRayTrace :: (Traced a, Num (Scalar (V a))) => a -> Trace (V a)
getRayTrace a = Trace $ \p v ->
SortedList $ filter (>= 0) (view unwrapped
$ (((getTrace a)^.unwrapping Trace) p v))
SortedList $ filter (>= 0) (op SortedList
$ (op Trace (getTrace a) p v))

-- | Compute the vector from the given point to the boundary of the
-- given object in the given direction, or @Nothing@ if there is no
-- intersection. Only positive scale muliples of the direction are returned
rayTraceV :: (Traced a, Num (Scalar (V a)))
=> Point (V a) -> V a -> a -> Maybe (V a)
rayTraceV p v a = case view unwrapped $ ((getRayTrace a)^.unwrapping Trace) p v of
rayTraceV p v a = case op SortedList $ op Trace (getRayTrace a) p v of
(s:_) -> Just (s *^ v)
[] -> Nothing

Expand All @@ -237,7 +241,7 @@ rayTraceP p v a = (p .+^) <$> rayTraceV p v a
maxRayTraceV :: (Traced a, Num (Scalar (V a)))
=> Point (V a) -> V a -> a -> Maybe (V a)
maxRayTraceV p v a =
case view unwrapped $ ((getRayTrace a)^.unwrapping Trace) p v of
case op SortedList $ op Trace (getRayTrace a) p v of
[] -> Nothing
xs -> Just ((last xs) *^ v)

Expand Down

5 comments on commit 4f56513

@jeffreyrosenbluth
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is slightly easier to read

@byorgey
Copy link
Member

@byorgey byorgey commented on 4f56513 Jan 3, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, though why not use appTrace instead of op Trace?

@jeffreyrosenbluth
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I feel that we should use our lens accessors whenever we can and that we left in the projections mostly for backwards compatibly. Also using op <Constructor> consistently means I don't have to remember newtype record field names. I think this is probably ready to merge now.

@byorgey
Copy link
Member

@byorgey byorgey commented on 4f56513 Jan 3, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'm fine with that.

@byorgey
Copy link
Member

@byorgey byorgey commented on 4f56513 Jan 3, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We left in some of the projections not just for backwards compatibility, but because they are semantically meaningful operations on their own. appTrace means "turn a trace into a function I can apply", which is a meaningful operation on traces. The fact that this so happens to be a newtype projection is just an implementation detail; one can imagine other implementations of trace where we would still have a function called appTrace with the same type signature, which is not a simple projection. In my opinion, users should be able to use the Trace API without actually knowing that it is a newtype. SortedList, on the other hand, is manifestly a newtype wrapper so using lenses to wrap and unwrap is the API. Anyway, not trying to argue, I don't think it's that important. Was just thinking about this and thought it was worth elaborating a bit.

I have a few more changes I want to make and then I'll merge if you're OK with them.

Please sign in to comment.