Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unified angle type #140

Merged
merged 10 commits into from Jan 8, 2014
Merged

Unified angle type #140

merged 10 commits into from Jan 8, 2014

Conversation

bergey
Copy link
Member

@bergey bergey commented Nov 27, 2013

This code is not at all ready to merge; this PR is for discussion.

This branch replaces the Angle type class with a single Angle type, and Isos to (de)construct Angles from various units. The important changes are in the first commit; the second begins the process of updating code to use the new type.

Motivation

The Angle class leads to frequent unwanted polymorphism. It leads to stranger types, also.

Semantics

Expressions such as "pi radians + 90 degrees" are well-defined. Making Angle a type allows such expressions to type check.

Syntax

lens lets us write any of these (type signatures added for clarity):

a = pi ^. from rad :: Angle
b = review deg 90 :: Angle
a ^. turn :: Double
view rad b :: Double
turn # 0.25 :: Angle -- (#) from Control.Lens, not from Diagrams

Discussion

I hope this syntax is nearly as nice as the current (pi :: Rad), with types that are closer to how we actually think about angles. I think it will make removing hardcoded Doubles easier. What do folks think?

bergey referenced this pull request in noinia/diagrams-lib Dec 4, 2013
@bergey
Copy link
Member Author

bergey commented Dec 4, 2013

With the latest patches, this branch builds. There's probably still documentation that doesn't match.

rotateBy = transform . rotation
-- | A synonym for 'rotate', interpreting its argument in units of
-- turns; it can be more convenient to write @rotateBy (1\/4)@ than
-- @'rotate' (1\/4 ^. from turn')@.
Copy link
Member

Choose a reason for hiding this comment

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

Missing open single quote?

@byorgey
Copy link
Member

byorgey commented Jan 3, 2014

In general, I like this a lot. It feels right and makes a lot of things so much simpler. However, I think we need a better story for constructing Angles. Using Control.Lens.# is completely out of the question, for obvious reasons. And stuff like 30 ^. from deg seems a little clunky. In an ideal world I would like to be able to write something as close to "30 deg" as possible. Obviously that isn't directly possible. But perhaps we could come up with some infix operator of type Double -> Iso' Angle Double -> Angle, so we could write 30 %&%^$ deg? (Obviously we need a better name for the operator...)

As an alternative, we could have deg :: Double -> Angle so we could write 30 # deg. Then the Iso would have to be named something else...

Just brainstorming here. I'm not sure I really like any of the above proposals.

@bergey
Copy link
Member Author

bergey commented Jan 3, 2014

So we need some operator that is not in Lens, not in Diagrams, and not profanity. There must still be a few of those.

Seriously, I agree that this would be better than any of the syntax examples I gave above. Some initial thoughts on names:

  • $$ (used in a bunch of parsing contexts)
  • @@
  • /- (loosely modeled on the angle symbol ∠)
  • Turn around the Iso so we can write 30 ^. deg :: Angle and define as = flip review to allow a as deg :: Double

Is there a reason you want Double -> Iso' Angle Double -> Angle rather than the general type b -> Iso' a b -> a? Or I guess the even more general type of flip review :: b -> AReview s t a b -> t?

I'd rather use the Isos than have separate Double -> Angle functions for each unit, if we can find a decent name for the operator.

@byorgey
Copy link
Member

byorgey commented Jan 3, 2014

Yes, I would also rather use the Isos than have separate Double -> Angle functions.

The reason I suggested Double -> Iso' Angle Double -> Angle is to make it easier for users to find. Though of course good documentation, examples, etc. will go a long way here too. b -> Iso' a b -> a might be OK too. I would really rather not have anything with stabs in it.

Turning around the Iso could work too, but I think I'd rather keep them the way they are, since it feels most natural to me. Converting from Angle to radians, degrees, etc. "feels like" a projection much more than constructing an Angle does.

I like @@. 30 @@ deg reads nicely. $$ could work, but it reminds me of function application and that doesn't make sense here: 1/4 $$ turn has nothing to do with applying 1/4 to turn. On the other hand I think $$ is occasionally used for backwards function application so that could be OK. /- looks like some sort of division which might be confusing: (tau / 7) /- rad.

@bergey
Copy link
Member Author

bergey commented Jan 3, 2014

Great. I just added @@ and switched -lib to using it internally. I still have some Haddock changes to make in -lib, and presumably lots of updates to make in -doc.

@byorgey
Copy link
Member

byorgey commented Jan 3, 2014

Cool, looks good to me.

@bergey
Copy link
Member Author

bergey commented Jan 4, 2014

I also meant to ask about precedence for @@. I picked a precedence lower than +, so I can write let a = b + c @@ turn. Are there other interactions we should think about?

@byorgey
Copy link
Member

byorgey commented Jan 4, 2014

Picking operator precedence is a black art. I never really know what the "right" way to approach it is. The precedence you picked for @@ "feels right" to me (for whatever that's worth).

@jeffreyrosenbluth
Copy link
Member

This looks very nice. Definitely preferable to what we had (IMHO).

bergey added a commit that referenced this pull request Jan 8, 2014
@bergey bergey merged commit 0244ad2 into master Jan 8, 2014
@bergey bergey deleted the unified-angle-type branch February 11, 2014 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants