-
Notifications
You must be signed in to change notification settings - Fork 21
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
Add Homogeneous and HomogeneousRowList for homogeneous rows #20
Add Homogeneous and HomogeneousRowList for homogeneous rows #20
Conversation
src/Type/Data/Record.purs
Outdated
:: ( RowToList record fields | ||
, FieldOf fields fieldType | ||
) | ||
=> RecordOf (Record record) fieldType |
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 think (Record record)
is the right thing to do here (as opposed to just record
) but it has the consequence of changing the type of a function beyond simply adding the type constraint.
For example, this:
foo :: forall a
. Record a
-> Record a
becomes:
foo :: forall a
. RecordOf a Boolean
=> a
-> a
Looks good, thanks! A few notes though:
|
@paf31 is the motivation for the |
Yes, since the type is already determined if the fundep is added anyway. |
Thanks for the feedback so far. Good call on moving this to Here's what I have so far: class Homogeneous row fieldType
instance homogeneous
:: ( RowToList row fields
, FieldOf fields fieldType
)
=> Homogeneous (? row) fieldType -- not sure what to do here
class FieldOf (rowList :: RowList) fieldType
instance fieldOfCons
:: (FieldOf tail fieldType)
=> FieldOf (Cons symbol fieldType tail) fieldType
instance fieldOfNil :: FieldOf Nil fieldType Does this seems like I'm on the right track? I'm not quite sure about the other 2 bullet points but eager to understand. |
@paulyoung instance homogeneous
:: ( RowToList row fields
, FieldOf fields fieldType
)
=> Homogeneous row fieldType Phil's point about The functional dependencies for
In cases where there is only one instance with all the arguments being type variables, I usually have both parameters always determined |
I don't think we can have both parameters determined, since that says you can predict the row given no information. |
* Add `TypeEquals` constraint on field type * Add funcitonal dependency for `FieldOf`
Thanks for the helpful feedback so far. I pushed some changes. |
Is there anything else I can do here? |
src/Type/Row.purs
Outdated
@@ -70,3 +74,17 @@ instance listToRowCons | |||
:: ( ListToRow tail tailRow | |||
, RowCons label ty tailRow row ) | |||
=> ListToRow (Cons label ty tail) row | |||
|
|||
|
|||
class Homogeneous (row :: # Type) fieldType |
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.
Also missing a functional dependency here.
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.
Good catch.
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.
Am I correct in thinking that the right thing to do here is | row -> fieldType
?
src/Type/Row.purs
Outdated
@@ -70,3 +74,17 @@ instance listToRowCons | |||
:: ( ListToRow tail tailRow | |||
, RowCons label ty tailRow row ) | |||
=> ListToRow (Cons label ty tail) row | |||
|
|||
|
|||
class Homogeneous (row :: # Type) fieldType |
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.
Could you please add a comment?
src/Type/Row.purs
Outdated
@@ -70,3 +74,17 @@ instance listToRowCons | |||
:: ( ListToRow tail tailRow | |||
, RowCons label ty tailRow row ) | |||
=> ListToRow (Cons label ty tail) row | |||
|
|||
|
|||
class Homogeneous (row :: # Type) fieldType |
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.
Perhaps a value-level function fieldType :: RProxy row -> Proxy fieldType
would be handy as well.
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.
Will do.
@LiamGoodacre Any thoughts on this? What do you think about creating some submodules here? |
Just been thinking about the fundeps and I'm thinking that this might suffer from the same issue I mentioned about multiple constraints. I'll try to come up with a demonstration tonight. |
Actually, I am mistaken. Ignore my previous concern. |
Submodules sound good. What do you suggest here? @paf31 |
src/Type/Row.purs
Outdated
@@ -70,3 +74,17 @@ instance listToRowCons | |||
:: ( ListToRow tail tailRow | |||
, RowCons label ty tailRow row ) | |||
=> ListToRow (Cons label ty tail) row | |||
|
|||
-- | Ensure that every field in a row has the same type. | |||
class Homogeneous (row :: # Type) fieldType |
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 though I'd asked this already but can't see it now.
Is | row -> fieldType
missing here?
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 I think so
Should I put this in a |
Sorry for the delay. Yes please. |
src/Type/Row/Homogeneous.purs
Outdated
, class Homogeneous | ||
) where | ||
|
||
-- | Ensure that every field in a row has the same type. |
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 comment should be removed, I think.
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. Strange things like this sometimes happen as a result of imports being managed by the PureScript Emacs layer.
src/Type/Row/Homogeneous.purs
Outdated
, FieldOf fields fieldType ) | ||
=> Homogeneous row fieldType | ||
|
||
class FieldOf (rowList :: RowList) fieldType | rowList -> fieldType |
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.
It's not clear to me (without reading the docs quite a bit) which one of these should be used in regular code. I'd suggest naming this one something like HomogeneousRowList
to just be explicit about it.
src/Type/Row/Homogeneous.purs
Outdated
class FieldOf (rowList :: RowList) fieldType | rowList -> fieldType | ||
instance fieldOfCons | ||
:: ( FieldOf tail fieldType | ||
, TypeEquals fieldType fieldType2 ) |
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.
Does this need TypeEquals
? Can you just use
instance fieldOfCons :: FieldOf tail fieldType => FieldOf (Cons symbol fieldType tail) fieldType
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 did that in 8b39b00#diff-86491d4ab8759f2c9d61332f39afdd9bR15 but you suggested using TypeEquals
in #20 (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.
D'oh. Thanks :)
That was incorrectly copied by the PureScript Emacs layer.
To better communicate which class should be used in regular code.
I think I've addressed everything in the latest round of feedback. |
src/Type/Row/Homogeneous.purs
Outdated
:: ( HomogenousRowList tail fieldType | ||
, TypeEquals fieldType fieldType2 ) | ||
=> HomogenousRowList (Cons symbol fieldType tail) fieldType2 | ||
instance fieldOfNil :: HomogenousRowList Nil fieldType |
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 suppose I should rename these to homogenousRowListCons
and homogenousRowListNil
Thanks! |
This is my first attempt at type-level programming. Hopefully it's pretty self explanatory, but the idea is to make sure that every field in a record has the same type.
Something similar can be achieved using
StrMap
, but it's not quite the same.This initial version is available to play with at http://try.purescript.org/?gist=bec330aab7a6c0b21e466e37483dfba9. It was originally adapted from http://try.purescript.org/?gist=2720825b0476c8924717437fb6f6eefb.
I think it would be great to support polymorphism and open rows, but I haven't had any success with that.
Any and all feedback is welcome.