OK, so here's an unusual one. Every time you see an example of Haskell's record syntax, it always looks like
Sphere {center = 0, radius = 2}
or similar. My question is... are those curly brackets actually part of the record syntax? Or are they actually shorthand for layout? In other words, can you actually write something like
Sphere
center = 0
radius = 2
and have it work?
I doubt it would be very useful to do this - it takes up a lot of visual space - but I'm just curious as to whether this is syntactically valid or not.
Layout is an alternative to explicit braces and semicolons.
Record syntax uses explicit braces and commas.
So no, you can't use layout as part of record syntax.
Haskell Report 2010 ยง2.7 Layout:
Haskell permits the omission of the braces and semicolons used in several grammar productions, by using layout to convey the same information.
OK, well I thought I'd put this question here in case anybody was interested. Having consulted the Haskell Report itself, it appears that the braces are literally a formal part of the record construct:
http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-690004.2.1
That means that these tokens actually have two distinct meanings in Haskell - as declaration delimiters when layout is not being used, and as record delimiters. I bet that leads to some interesting parser edge-cases!
(I also note in passing that EmptyDataDecls appears to be on by default in Haskell 2010, which is worth knowing...)
After Sphere, the lexer won't insert a brace. Why should it? You dont expect a brace inserted in code like:
z = x
+ y
either, do you?
Related
I can see from plenty of Q&As that cpp is the usual preprocessor for Haskell source; but that it isn't a good fit for the job. What other options are there?
Specifically:
Haskell syntax is newline-sensitive and space/indent-sensitive -- unlike C, so cpp just tramples on whitespace;
' in Haskell might surround a character literal, but also might be part of an identifier (in which case it won't be paired) -- but cpp complains if not a char literal;
\ gets a trailing space inserted -- which is not a terrible inconvenience, but I'd prefer not.
I'm trying to produce a macro to generate an instance from parameters for a newtype type and corresponding data constructor. It needs to generate both the instance head and constraints and a method binding. By just slotting the constructors into an instance skeleton.
(Probably Template Haskell could do this; but it seems rather a large hammer.)
cpphs seems to be just about enough for my (limited) purposes. I'm adding this answer for the record; an answer suggesting cpphs (and some sensible advice to prefer Template Haskell) was here and then gone.
But there's some gotchas that meant at first sight I'd overlooked how it helped.
Without setting any options, it behaves too much like cpp to be helpful. At least:
It doesn't complain about unpaired '. Indeed you can #define dit ' and that will expand happily.
More generally, it doesn't complain about any nonsense input: it grimly carries on and produces some sort of output file without warning you about ill-formed macro calls.
It doesn't insert space after \.
By default, it smashes together multiline macro expansions, so tramples on whitespace just as much.
Its tokenisation seems to get easily confused between Haskell vs C. specifically, using C-style comments /* ... */ seems to upset not only those lines, but a few lines below. (I had a #define I wanted to comment out; should have used Haskell style comments {- ... -} -- but then that appears in the output.)
The calling convention for macros is C style, not Haskell. myMacro(someArg) -- or myMacro (someArg) seems to work; but not myMacro someArg. So to embed a macro call inside a Haskell expression probably needs surrounding the lot in extra parens. Looks like (LISP).
A bare macro call on a line by itself myInstance(MyType, MyConstr) would not be valid Haskell. The dear beastie seems to get easily confused, and fails to recognise that's a macro call.
I'm nervous about # and ## -- because in cpp they're for stringisation and catenation. I did manage to define (##) = (++) and it seemed to work; magicHash# identifiers seemed ok; but I didn't try those inside macro expansion.
Remedies
(The docos don't make this at all obvious.)
To get multi-line output from a multi-line macro def'n, and preserving spaces/indentation (yay!) needs option --layout. So I have my instance definition validly expanded and indented.
If your tokenisation is getting confused, maybe --text will help: this will "treat input as plain text, not Haskell code" -- although it does still tolerate ' and \ better. (I didn't encounter any downsides from using --text -- the Haskell code seemed to get through unscathed, and the macros expanded.)
If you have a C-style comment that you don't want to appear in output, use --strip.
There's an option --hashes, which I imagine might interact badly with magicHash#.
The output file starts with a header line #line .... The compiler won't like that; suppress with --noline.
I would say that Template Haskell is the most perfect tool for this purpose. It is the standard set of combinators for constructing correct Haskell source code. After that there is GHC.Generics, which might allow you to write a single instance that would cover any type which is an instance of Generic.
I'm trying to ask a question on our friendly neighboring site, math.stackexchange.com and I'm new to mathjax and couldn't get what I need from this: https://math.meta.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference so I have come here for help.
I'm trying to show lambda is an element of the set (2,3) but I can't get the curly brackets/braces to be it. I can write it using parentheses, but not brackets (it makes a difference).
currently, I have $\lambda \in (2,3)$ but what I need are for those parentheses to be curly braces, and I can't figure it out.
Thanks!
MathJax is largely a subset of LaTeX, so when in doubt, refer to TeX documentation.
In this case, you need to know that curly braces are a common delimiter in TeX, and so they have to be escaped if you literally mean curly braces.
So, what you need is $\lambda \in \{ 2,3 \}$. Make sense?
Background
Most style guides recommend keeping line lengths to 79 characters or less. In Haskell, indentation rules mean that expressions frequently need to be broken up with new lines.
Questions:
Within expressions, where is it legal to place a new line?
Is this documented somewhere?
Extended question: I see GHC formatting my code when it reports an error so someone has figured out how to automate the process of breaking long lines. Is there a utility that I can put haskell code into and have it spit that code back nicely formatted?
You can place a newline anywhere between lexical tokens of an expression. However, there are constraints about how much indentation may follow the newline. The easy rule of thumb is to indent the next line to start to the right of the line containing the expression. Beyond that, some style things:
If you are indenting an expression that appears in a definition name = expression, it's good style to indent to the right of the = sign.
If you are indenting an expression that appears on the right-hand side of a do binding or a list comprehension, it's good style to indent to the right of the <- sign.
The authoritative documentation is probably the Haskell 98 Report (Chapter 2 on lexical structure), but personally I don't find this material very easy to read.
str = "fa, (captured)[asd] asf, 31"
for word in str:gmatch("\(%a+\)") do
print(word)
end
Hi! I want to capture a word between parentheses.
My Code should print "captured" string.
lua: /home/casey/Desktop/test.lua:3: invalid escape sequence near '\('
And i got this syntax error.
Of course, I can just find position of parentheses and use string.sub function
But I prefer simple code.
Also, brackets gave me a similar error.
The escape character in Lua patterns is %, not \. So use this:
word=str:match("%((%a+)%)")
If you only need one match, there is no need for a gmatch loop.
To capture the string in square brackets, use a similar pattern:
word=str:match("%[(%a+)%]")
If the captured string is not entirely composed of letters, use .- instead of %a+.
lhf's answer likely gives you what you need, but I'd like to mention one more option that I feel is underused and may work for you as well. One issue with using %((%a+)%) is that it doesn't work for nested parentheses: if you apply it to something like "(text(more)text)", you'll get "more" even though you may expect "text(more)text". Note that you can't fix it by asking to match to the first closing parenthesis (%(([^%)]+)%)) as it will give you "text(more".
However, you can use %bxy pattern item, which balances x and y occurrences and will return (text(more)text) in this case (you'd need to use something like (%b()) to capture it). Again, this may be overkill for your case, but useful to keep in mind and may help someone else who comes across this problem.
While looking through the Snap.svg tutorial, I came across the following line of code that made me do a double take:
// Now lets create pattern
var p = s.path("M10-5-10,15M15,0,0,15M0-5-20,15")
What is M10-5-10,15? At first, I thought it may have been some kind of coordinate-range syntax, but that wouldn't really make much sense in this case, and I couldn't find anything remotely close to that in the SVG path spec. I also couldn't find anything of note in the Snap.svg docs.
Interestingly enough, that code does seem to draw the desired pattern...
The simplest answer is often the right one. There is no special syntax - the coordinates are just concatenated together with no white space.
The clue is the command: M is the moveto command, which doesn't normally draw anything. If you look in the spec, however, you'll notice the following:
If a moveto is followed by multiple pairs of coordinates, the
subsequent pairs are treated as implicit lineto commands.
So, a moveto can actually have multiple coordinate pairs, and anything after the first pair is treated as a lineto command. The mystery syntax is, in reality, just a concise (but less readable) way of writing M10,-5 -10,15 M15,0 0,15 M0,-5 -20,15, the hyphens being the negative signs.
Simply looking at the SVG path grammar also shows quite clearly that the arguments to moveto are coordinate-pairs, and coordinates are simple numbers.
I suppose the key thing to take away is that SVG paths don't really need whitespace or commas, unless the numbers would be ambiguous without them.