
On Wed, 16 Feb 2011 06:25:54 +0200, Michael Snoyman
It looks good. Instead of the mkSize TH function, if you just define an IsString instance, then anyone using OverloadedStrings will be able to use string literals. I haven't confirmed this yet, but it might even be possible to embed those string literals inside Cassius and GHC will still apply fromString appropriately.
I was thinking about it. But as I understand, it would not work unless you explicitly specify the resulting size type. E.g. let s = fromString "100px" How would GHC know that in this case fromString for PixelSize should be used? This would force you to add explicit (s :: PixelSize) type. This is something I want to avoid: Type should be determined from string constant. Or am I missing something?
As far as variables inside templates: I personally think that's crossing the line again into stuff templates shouldn't be dealing with, but I'm open for discussions. Since templates tie in so well with Haskell, I just don't think it's worth adding a whole bunch of extra code and syntax to make it work.
I understand this is a feature which may be used inappropriately. But here is mine justification for it: Consider you want to write a simple Cassius template: #a height: 100px #b width: 100px #a and #b are related and their width and height should be always the same. So it makes perfect sense to define (commonSize = $(mkSize "100px")) and use it instead of literals. I know that commonSize is needed and used only for that Cassius template, but I have to define it in an external Haskell module. That makes template not self-contained and harder to read, pollutes Haskell code with declarations that should be local to a template. IMO this cases illustrates how local template variables may be the right solution: #{let commonSize = $(mkSize "100px")} #a height: #{commonSize} #b width: #{commonSize} Regards, Dmitry
Michael
On Tue, Feb 15, 2011 at 10:55 PM, Dmitry Kurochkin
wrote: Hi Yesod developers.
Attached are two modules to implement CSS size wrappers for Hamlet. It implements several types for different CSS units:
* em - EmSize * ex - ExSize * px - PixelSize * % - PercentageSize * cm, in, mm, pc, pt - AbsoluteSize
You can create them using an mkSize Template Haskell function, e.g.
let size = $(mkSize "100%")
All types are instances of Show, Eq, Ord, Num, Fractional and ToCss. This allows you to do math and interpolate it to Hamlet.
Ideally, I wanted to have only one type and make an implicit conversion from string literals. But I do not know how to forbid mixing of incompatible units in math (e.g. 10px + 10cm) with a single type. And I do not know how to make implicit conversion from string literals with multiple types.
I would appreciate any comments. Including on naming style, type design, API and overall usefulness. Keep in mind that this is the first time I use Template Haskell, so the code may be not optimal and plain ugly (e.g. can we use quasi quotes instead of directly messing with TH?)
BTW Michael, one more thing I miss in Hamlet is defining variables in templates. I would prefer to put simple CSS-related constants directly in Cassius instead of a dedicated module. Is it possible to implement?
Regards, Dmitry