Closed mdgriffith closed 7 years ago
I don't find this solution particularly crazy. This could potentially also lead to making the actual types of atoms and properties more opaque (that is, not exposing the fact that Properties are actually functions), but I couldn't come up with a way to make this work without typeclasses.
The type signature of |-
could also be more specific to prevent it from being used as a generic <<
replacement:
(|-) : (a -> a) -> (a -> a) -> (a -> a)
As a perhaps simpler alternative, how about using a nested list structure?
class LargerStyle
[ font
[ Font.named roboto
, Font.size 18
, Font.letterSpacing 20
, Font.light
, Font.align center
, Font.uppercase
, Font.color Color.blue
]
, box
[ width (px 100)
, height (px 100)
, padding (all 5)
]
]
where
font : List FontProperty -> Property
box : List BoxProperty -> Property
That makes a lot of sense!
This was resolved using obsp's suggestion! No crazy infix operators.
To start this off I think Elm's avoidance of infix operators is generally a really good design decision.
That being said, I'm running into an interesting issue. In
style-elements
we want to have grouped properties, which was initially proposed using the pipeline operator. This looks something like this:The problem I ran into is that for this to work out in types, then each category is just a
Property
and each modifier is aProperty -> Property
. This actually means that you could have something like this:This is weird. It means the groups aren't enforced in the type level. Also, with the above type signature you could just have the empty
box
property which doesn't do anything. Again, sorta weird.I can make the above code issue a runtime error if you try to mix up the functions with the starting "atoms", but obviously I'd much rather have a compiler error.
This is compounded by the fact that the
Property
type is actuallyProperty class variation animation
, because the library needs to keep track of what types are being used for classes, variations and animations. SoProperty -> Property
shows up asProperty class variation animation -> Property class variation animation
, which is kinda weird for a function that does something like "set border color".Alternative
Here's an example of what I'd like a modifier function to actually look like:
Border.color : Color -> Border -> Border
Given the above code, the "atom" can't just be of type
Border
though, which it would need to be in order for pipelines to work out. The reason being is that a style class is gotta be a list of one type, so what happens when we have a Font with our border?So, the "atom" needs to take a
Border
and transform it into aProperty class variation animation
.Actually the atom needs to take a
Border -> Border
and transform it into a property for this to work.Here's what the final code turns out to be to make the groups actually enforced:
We're composing a huge function and then feeding it into the atom, which seeds it with an empty
Border
orBox
orFont
, and then transforms that into aProperty
. Conceptually I don't think that's too crazy, but the reason I'm posting this issue is for feedback on if I'm nuts.An immediate issue of the above syntax is that
elm-format
will reformat it to look super funky because<|
is really meant for inline statements, not pipelines.Aesthetically, it's also really busy. The vertical line in
|>
created a nice continuity for each group.So, here's the solution I'm looking at. Essentially we're defining two "new" infix operators that do nearly the exact thing as the above.
The infix operators would be defined in the library as: