I'm new at Haskell and Alex.
I'm trying to make tokens of operators in Lexer.x
here is an example of my code
\<= { \s -> TLE }
\== { \s -> TEQ }
\/= { \s -> TNEQ }
\&& { \s -> TAND }
but when I wrote
\|| { \s -> TOR }
I got a parse error on this line
How I should make token for || ?
You can use string literals to prevent escaping all characters, so you can use:
"||" { \s -> TOR }
Related
I've got this section of code:
class Main {
static inline function difference(a:Int, b:Int, ?f:(Int, Int) -> Int):Int {
if (f == null) {
f = (a, b) -> a - b;
}
return f(a, b);
}
static function main() {
trace(difference(42, 37));
trace(difference(42, 37, (a, b) -> a - b));
}
}
Which, when I compile using haxe --main Main, fails with this error:
Main.hx:11: characters 15-50 : Cannot modify a closure parameter inside inline method
Main.hx:11: characters 15-50 : For function argument 'v'
If I change Main.difference to not be inline, this error doesn't come up and everything compiles fine.
Why does this error occur?
Edit: I've found out I can also assign the argument to a variable first, and then pass the variable to Main.difference, like this:
static function main() {
var f = (a, b) -> a - b;
trace(difference(42, 37, f));
}
Which works fine with Main.difference being inlined. How does assigning the function to a variable first change things though?
This is related to how inline functions are unwrapped by the compiler. Let us take a simpler variant of your code:
class HelloWorld {
static inline function difference(a:Int, b:Int, ?f:(Int, Int) -> Int):Int {
return f(a, b);
}
static function main() {
trace(difference(42, 37, (a, b) -> a - b));
}
}
When disabling optimizations, this will yield the following JavaScript:
HelloWorld.main = function() {
console.log("HelloWorld.hx:14:",(function(a,b) {
return a - b;
})(42,37));
};
So the body of difference has been incorporated into main using a JavaScript closure. My best guess for what is happnening in your exact case is something like this:
HelloWorld.main = function() {
var v = function(a,b) {
return a - b;
}
console.log("HelloWorld.hx:14:", (function(a,b) {
if (v == null) {
v = function(a, b) {
return a - b;
}
}
return v(a, b);
})(42, 37));
};
This alters the value of v, which exists outside of difference, which has been automatically placed there as a binding for the anonymous lambda. This is what the compiler is trying to avoid. This would not be the end of the world in your case, but in general this is bad and would lead to issues in many programs.
There is a way to inline this code perfectly by hand without this, but I think that there is some weirdness surrounding how annonymous lambdas are currently handled. The situation may improve in the future.
When you explicitly defined f in main, the compiler is intelligent enough to rename the nested f as f1, which is why the issue does not occur:
HelloWorld.main = function() {
var f = function(a,b) {
return a - b;
};
var f1 = f;
if(f1 == null) {
f1 = function(a,b) {
return a - b;
};
}
console.log("HelloWorld.hx:14:",f1(42,37));
};
But this would also work if the inline part of this function is important to you:
class HelloWorld {
static inline function difference(a:Int, b:Int, ?f:(Int, Int) -> Int):Int {
var h = f;
if (h == null) {
h = (a, b) -> a - b;
}
return h(a, b);
}
static function main() {
trace(difference(42, 37, (a, b) -> a - b));
}
}
I'm having a problem because of lambda. It says that it has unexpected tokens but there are no helpful solutions in the debugger. I am new to programming and I have no idea what to do especially because in the tutorial I follow it's the same thing with no errors. The code and the screenshot are bellow. Thanks
image
when {
getButtonText == "Edit Profile" -> startActivity(
Intent(
context,
AccountSettingsActivity::class.java
)
)
getButtonText == "Follow" -> {
firebaseUser?.uid.let { it1 ->
FirebaseDatabase.getInstance().reference
.child("Follow").child(it1.toString())
.child("Following").child(profileId)
.setValue(true)
}
firebaseUser?.uid.let { it1 ->
FirebaseDatabase.getInstance().reference
.child("Follow").child(profileId)
.child("Followers").child(it1.toString())
.setValue(true)
}
}
}
getButtonText == "Following" -> {
firebaseUser?.uid.let { it1 ->
FirebaseDatabase.getInstance().reference
.child("Follow").child(it1.toString())
.child("Following").child(profileId)
.removeValue()
}
firebaseUser?.uid.let { it1 ->
FirebaseDatabase.getInstance().reference
.child("Follow").child(profileId)
.child("Followers").child(it1.toString())
.removeValue()
}
}
}
} <<<<
getButtonText == "Following" ->
The marked bracket is closing the when block and should be removed. When using Android Studio you should be able to hit Ctrl+Alt+L to auto fix your formatting, including indentation. This will probably help you spot these kind of mistakes in the future
post "/introduceAnIdea" $ do
command <- jsonData
json $ handle command
How would you remove the do and change it with >>= ?
post "/introduceAnIdea" $ jsonData >>= (json . handle)
I don't think that's necessarily better in this case though.
Here's how to rewrite do-notation as >>= and >>: (NB: a newline becomes ; in the c-like notation option, which I use here.)
do { a <- m; b... } = m >>= \a -> do { b... }
do { a; b... } = a >> do { b... }
do { a } = a
So this becomes:
post "/introduceAnIdea" $ do { command <- jsonData; json $ handle command}
= post "/introduceAnIdea" $ jsonData >>= \command -> do {json $ handle command}
= post "/introduceAnIdea" $ jsonData >>= \c -> json $ handle c
I have a swift implementation of the haskell <*> operator that seems to work as long as the arguments are arrays:
public func <*> <T, U>(left:[(T)->U], right:[T]) -> [U] {
return flatten(map(left) { (function) -> [U] in
return map(right) { return function($0) }
})
}
I'm trying to make it more general by rewriting it to use sequences instead of arrays, but I'm having difficulty with the syntax to require that a sequence be a sequence of functions. This works to generalize the right argument, but not the left:
public func <*> <T, U, Tseq:SequenceType where Tseq.Generator.Element == T>(left:[(T)->U], right:Tseq) -> [U] {
return flatten(map(left) { (function) -> [U] in
return map(right) { return function($0) }
})
}
Now I'm trying to generalize the left part, but running into syntax errors. It seems like it ought to be:
public func <*> <
T,
U,
Tseq:SequenceType where Tseq.Generator.Element == T,
Fseq:SequenceType where Fseq.Generator.Element == (T) -> U
>(left:[(T)->U], right:Tseq) -> [U] {
return flatten(map(left) { (function) -> [U] in
return map(right) { return function($0) }
})
}
But that gives me an error on the Fseq... line:
Expected '>' to complete generic parameter list
What is the proper syntax (or is there no proper syntax) to require that Fseq.Generator.Element be a function taking a T and returning a U?
Couple of problems (one fixable, one more fatal):
You have the syntax for the generic template a bit off. There’s only one where clause for all the placeholders, rather than an optional one per placeholder. So it would be more like:
public func <*> <
T, U, Tseq: SequenceType, Fseq: SequenceType
where Fseq.enerator.Element == T -> U,
Tseq.Generator.Element == T>
(left:[(T)->U], right:Tseq) -> [U] {
return flatten(map(left) { (function) -> [U] in
return map(right) { return function($0) }
})
}
However, that still won’t work because you can’t have expressions more complex than single types on the rhs of a == (not even tuples of two placeholders). So where Fseq.Generator.Element == T->U is not going to fly.
You might want to look at how swiftz does this – looks like it requires an additional struct.
I use GraphViz with the following dot file:
digraph G
{
rankdir=LR;
subgraph commits
{
"5c071a6b2c" -> "968bda3251" -> "9754d40473" -> "9e59700d33" -> "2a3242efa4";
}
subgraph annotations
{
"V1.0" [shape=box];
"br/HEAD" [shape=box];
"V1.0" -> "9e59700d33" [weight=0];
"br/HEAD" -> "2a3242efa4" [weight=0];
}
}
It give me something like that:
But I want something like that:
V1.0 br/HEAD
| |
\/ \/
5c071a6b2c -> 968bda3251 -> 9754d40473 -> 9e59700d33 -> 2a3242efa4
How can I do that?
For your help,
Thanks by advance.
This will align the annotations with the commits:
digraph G
{
rankdir=LR;
subgraph commits
{
"5c071a6b2c" -> "968bda3251" -> "9754d40473" -> "9e59700d33" -> "2a3242efa4";
}
subgraph annotations1
{
rank="same";
"V1.0" [shape=box];
"V1.0" -> "9e59700d33" [weight=0];
}
subgraph annotations2
{
rank="same";
"br/HEAD" [shape=box];
"br/HEAD" -> "2a3242efa4" [weight=0];
}
}
Since the rank="same"; effects the whole subgraph I had to split the annotations in two different subgraphs.
Result is: