-
Notifications
You must be signed in to change notification settings - Fork 71
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
Refactor syntax/type level programming to YesNo #151
Refactor syntax/type level programming to YesNo #151
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for getting to this so quickly.
A few things should be renamed to better distinguish the value-level and type-level instances. There's also a few instance names that need to be renamed. Other than that, it looks good.
|
||
foreign import kind Boolean | ||
foreign import kind YesNo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way this is defined, it's hard to see the difference between then YesNo
type and the YesNo
kind. Elsewhere in this PR, you use YesNoKind
, which is correct and which I'd prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say that this change should then propagate throughout and then we should have
foreign import kind YesNoKind
foreign import data YesK :: YesNoKind
foreign import data NoK :: YesNoKind
as well, shouldn't we? Otherwise the Yes/No
might get confused with the value-level instances
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I replied to your later comment, but stating it again here: yes, let's do it that way.
@@ -19,11 +19,11 @@ foreign import data Value_Level_Instance2 :: Value_Level_Type_Kind | |||
-- despite the "foreign import" syntax! | |||
---------------------- | |||
|
|||
-- Using the value-level type Boolean as an example... | |||
data Boolean_ = True_Value | False_Value | |||
-- Using a Boolean-like value-level type as an example... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that you have referred to Boolean
here as the analogy of YesNo
. However, it will likely make others wonder why Boolean
itself wasn't just used, leading them to open a new issue.
Perhaps this comment should include a link to the corresponding issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I don't think it would be too problematic is that you already talk about the fact that Boolean
is an internal type and you change slightly the names in some places so there's no overlap. But sure, once we get the Boolean
info written it won't hurt to have a link
foreign import data True :: Boolean | ||
foreign import data False :: Boolean | ||
foreign import data Yes :: YesNo | ||
foreign import data No :: YesNo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This no longer distinguishes the instance (e.g. data YesNo = Yes
) from the type (e.g. kind YesNoKind = Yes
).
Perhaps we should distinguish it like this...?
data YesNo = Yes_Value | No_Value
foreign import kind YesNoKind
foreign import data Yes :: YesNoKind
foreign import data No :: YesNoKind
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about going with
data YesNo = Yes | No
foreign import kind YesNoKind
foreign import data YesK :: YesNoKind
foreign import data NoK :: YesNoKind
like I mentioned in the first comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that sounds good.
instance toInt_FalseZero :: ToInt False Zero | ||
class ToInt (input :: YesNo) (output :: ZeroOrOne) | input -> output | ||
instance toInt_TrueOne :: ToInt Yes One | ||
instance toInt_FalseZero :: ToInt No Zero |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These instances should be renamed to toInt_YesOne
and toInt_NoZero
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, missed these
foreign import kind YesNoKind | ||
foreign import data Yes :: YesNoKind | ||
foreign import data No :: YesNoKind | ||
data YesNoProxy (a :: YesNoKind) = YesNoProxyInstance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I'm including this comment in case the question comes to mind due to other renaming comments in this review)
This could be renamed to YesNoKindProxy
, but I think that's unnecessary. So, I think this should be left as you have it now.
Amended the commit to include changes we discussed, hope I didn't miss any line, if you see something missing let me know. closes #152 edit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you missed two things. Just push another commit that fixes that. No need to clean up the commit history since I can squash the commit into one.
foreign import data False :: BooleanKind | ||
foreign import kind YesNoKind | ||
foreign import data Yes :: YesNoKind | ||
foreign import data No :: YesNoKind |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you forgot to use the same name scheme (YesK/NoK)
falseK :: BooleanProxy False | ||
falseK = BooleanProxyInstance | ||
noK :: YesNoProxy No | ||
noK = YesNoProxyInstance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and update the YesNoProxy [Yes/No]
to [YesK/NoK] here, too.
While applying the last fixes I found out that the example with > :p
… toRed :: YesNoProxy YesK -> String
… toRed _ = "red"
…
> reifyYesNo Yes toRed
Error found:
in module $PSCI
at line 1, column 16 - line 1, column 16
Could not match type
b0
with type
YesK
while trying to match type YesNoProxy b0
with type YesNoProxy YesK
while checking that expression toRed
has type YesNoProxy b0 -> t1
in value declaration it
where b0 is a rigid type variable
bound at line 1, column 16 - line 1, column 16
t1 is an unknown type
See https://github.com/purescript/documentation/blob/master/errors/TypesDoNotUnify.md for more information,
or to contribute content related to this error. And I'm sure it's because of I'm not sure why this is happening, shouldn't |
Those aren't supposed to work (hence why they are commented out). I wrote that section when I didn't fully understand how that concept (using type-level functions to compute things via unification) was even possible. Sometime later, I wrote this file, which shows why that idea is actually accurate. This PR reminded me that I hadn't fixed that explanation yet, so I was hoping to fix it after you finished the PR. Edit: Thus,
|
Alright then, I think I'm done fixing all the stuff we discussed so far so you can hopefully merge this now so we can get to the next thing |
Looks good. Thanks for your contribution! |
(Added by Jordan): This change was introduced due to discussion in #139