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

Clarify what's unused #13

Merged
merged 4 commits into from
Jul 24, 2019
Merged

Clarify what's unused #13

merged 4 commits into from
Jul 24, 2019

Conversation

treeowl
Copy link
Contributor

@treeowl treeowl commented Jul 18, 2019

Following profunctors, make the types indicate what's unused.

Following `profunctors`, make the types indicate what's unused.
@chessai
Copy link
Collaborator

chessai commented Jul 18, 2019

Ah, neat trick. I didn't know about this. Waiting for travis, then I'll take another look.

@chessai
Copy link
Collaborator

chessai commented Jul 18, 2019

@sjakobi what are your thoughts on this? I'm in favour. The only drawback might be that type errors are slightly more confusing, though it's unlikely that users are going to pass anything but a function in practise anyway. also, perhaps the use of this trick should be documented.

@treeowl
Copy link
Contributor Author

treeowl commented Jul 18, 2019

I'm not so sure about the type variable name/presentation. I think we should use something infix to suggest a function arrow. Since we can't use actual operator characters in a type variable, maybe something like a `arr` b?

@treeowl
Copy link
Contributor Author

treeowl commented Jul 18, 2019

Or maybe a `to` b?

@sjakobi
Copy link
Collaborator

sjakobi commented Jul 18, 2019

Neat idea!

We have the following note in the haddocks:

All of the functions in this module take an argument that solely directs the type of the coercion. The value of this argument is ignored.

So how about something like

type Director a b = a -> b

We could then have haddocks on the type alias.

@sjakobi
Copy link
Collaborator

sjakobi commented Jul 18, 2019

BTW @chessai, had you seen sjakobi/newtype-generics#5? I sometimes feel bad about having this neat API just lying around. I suspect that it's actually better than what either coercible-utils or newtype-generics currently offer.

@chessai
Copy link
Collaborator

chessai commented Jul 18, 2019

Neat idea!

We have the following note in the haddocks:

All of the functions in this module take an argument that solely directs the type of the coercion. The value of this argument is ignored.

So how about something like

type Director a b = a -> b

We could then have haddocks on the type alias.

I think I'd prefer something more like type Director p a b = p a b. That way they could pass anything of kind Type -> Type -> Type. But, perhaps this flexibility is unnecessary, and
your type alias would be preferred, since the only goal here is clarity of consumption.

@treeowl
Copy link
Contributor Author

treeowl commented Jul 18, 2019

I'm not a fan of this Director business, for two main reasons. One is that I'm opposed to type synonyms in most cases; they add mental indirection for nothing here. Also, I don't even see how that's supposed to be mnemonically helpful here. Much better, I think, to give the type variable a name that indicates what it's supposed to do.

@treeowl
Copy link
Contributor Author

treeowl commented Jul 18, 2019

I think the right place to document what the to/arr/coerceTo type variables are about is the documentation at the top of the module.

@treeowl
Copy link
Contributor Author

treeowl commented Jul 18, 2019

By the way... if you want to keep precisely the same API as before while still communicating the same thing, one option would be

class IsArrow p | -> p
instance IsArrow (->)
-- or
class IsArrow p where
  type Silly p -- banish overlapping instances
instance p ~ (->) => IsArrow p where
  type Silly (->) = ()
(#.) :: (Coercible b c, IsArrow p) => p b c -> (a -> b) -> a -> c
(#.) _ = coerce	(#.) _ = coerce

This means the argument will be inferred as having a function type, but (#.) can't make use of that fact. I don't think this is really a good idea, but I figured I'd mention it...

@chessai
Copy link
Collaborator

chessai commented Jul 18, 2019

I'm not a fan of this Director business, for two main reasons. One is that I'm opposed to type synonyms in most cases; they add mental indirection for nothing here. Also, I don't even see how that's supposed to be mnemonically helpful here. Much better, I think, to give the type variable a name that indicates what it's supposed to do.

I generally share this opinion. Type synonyms are generally distracting, I only like using them for quick hacking. Almost all usage of type synonyms are banned at work, except for the common transformers+Identity story.

Okay, I think we should just name p to something useful and make it infix.

@treeowl
Copy link
Contributor Author

treeowl commented Jul 18, 2019

@chessai, for what it's worth, I have found more uses for type synonyms than that. Several higher-rank ones can be useful, like type f ~> g = forall x. f x -> g x, and stuff from lens (though that's always controversial). In heavily typish code they often show up with type families, such as

type family ReverseOnto acc xs where
  ReverseOnto acc '[] = acc
  ReverseOnto acc (x ': xs) = ReverseOnto (x ': acc) xs

type Reverse xs = ReverseOnto '[] xs

I recently found them useful for working around nasty limitations of the type role system, where sticking a newtype in how I'd prefer prevented necessary coercions (the whole mess got wrapped under a newtype before exposing it to the world anyway).

My final "approved by me!" use for type synonyms is as throw-away constraint synonyms appearing once as a superclass constraint, once as an instance constraint, and never again.

type CS a b c d = (Blah a, Boop a b, Bleep b c, Huh c d b, .......)
class CS a b c d => C a b c d
instance CS a b c d => C a b c d

Sorry for the irrelevant ramble; can't help myself.

@chessai
Copy link
Collaborator

chessai commented Jul 18, 2019

it's ok; i enjoy your rambles. i can see uses for all of those.

@sjakobi
Copy link
Collaborator

sjakobi commented Jul 19, 2019

Yeah, Director wasn't a good name.

I'd be fine with something like

a `to` b

or

coerce a b

Although I'd like to see the haddocks before we make the final decision.

@treeowl
Copy link
Contributor Author

treeowl commented Jul 23, 2019

I changed the name of the type variable and updated the documentation.

@treeowl treeowl mentioned this pull request Jul 23, 2019
src/CoercibleUtils.hs Outdated Show resolved Hide resolved
Co-Authored-By: Simon Jakobi <simon.jakobi@gmail.com>
@sjakobi sjakobi merged commit c47c437 into love-haskell:master Jul 24, 2019
@sjakobi
Copy link
Collaborator

sjakobi commented Jul 24, 2019

Thank you @treeowl! :)

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