Using named function declaration instead of anonymous function in Elm - elm

In the REPL, if I use
> String.filter (\char -> char /= '-') "800-555-1234"
I get the result:
"8005551234" : String
as expected.
But if instead of the anonymous function I use a named function declaration like this:
> String.filter (isKeepable char = char /= '-') "800-555-1234"
I get this error:
-- SYNTAX PROBLEM -------------------------------------------- repl-temp-000.elm
The = operator is reserved for defining variables. Maybe you want == instead? Or
maybe you are defining a variable, but there is whitespace before it?
3| String.filter (isKeepable char = char /= '-') "800-555-1234"
^
Maybe <http://elm-lang.org/docs/syntax> can help you figure it out.
This seems odd to me, since the function declaration itself is an expression that returns a function object:
> isKeepable char = char /= '-'
<function> : Char -> Bool
So why can't that function reference be passed to filter like any expression that evaluates to a function?

Named function declarations are only valid at the top level or in a let clause. Try this instead:
> let isKeepable char = char /= '-' in String.filter isKeepable "800-555-1234"

Related

This expression has type 'a -> 'a array array but an expression was expected of type 'b array

How is it possible to correctly manipulate a matrix in Ocaml?
What am I missing here, when assigning a value to a position on the matrix?
let dynamic arraymoedas valor len =
let arrayAux = Array.make_matrix (len+1) (len+1) in
for i=0 to len+1 do
arrayAux.(i).(0)=0;
done;
for j=0 to valor+1 do
arrayAux.(0).(j)= max_int
done;
for i=1 to len+1 do
for j=1 to len+1 do
if(arraymoedas.(i-j) > j) then
arrayAux.(i).(j) = arrayAux.(i - 1).(j)
else
arrayAux.(i).(j) = min (1+arrayAux.(i).(j-arraymoedas.(i - 1))) arrayAux.(i-1).(j)
done;
done;
!arrayAux
Error:
File "Novo_func.ml", line 38, characters 8-16:
38 | arrayAux.(i)(0)=0;
^^^^^^^^
Error: This expression has type 'a -> 'a array array
but an expression was expected of type 'b array
As identified in the comments, there are three issues with the code you've written.
Primarily, you're not using Array.make_matrix properly. This function has type int -> int -> 'a -> 'a array array. You've only supplied the dimensions, but not a default value. When you do this, you get back a function that takes in the default value and returns an array of arrays.
Secondly, when modifying the values in an array, use <- instead of =. Rather than arrayAux.(0).(j) = max_int you want to use arrayAux.(0).(j) <- max_int.
Thirdly, at the end of your dynamic function, you're using the ! operator to deref arrayAux. The problem with this is that arrayAux is not a reference. This will cause a compiler error due to a type mismatch.

XOR reverse a string in objective-c get an error

I want to use the following code to reverse a char * type string in objective-c:
- (char *)reverseString:(char *)aString
{
unsigned long length = strlen(aString);
int end = length - 1;
int start = 0;
while (start < end) {
aString[start] ^= aString[end];
aString[end] ^= aString[start];
aString[start] ^= aString[end];
++start;
--end;
}
return aString;
}
But I got an error EXC_BAD_ACCESS at this line
aString[start] ^= aString[end]
I googled and found people said I can't modify a literal string because it is readonly. I am new to C so I wonder what simple data type (no object) I can use in this example? I get the same error when I use (char []) aString to replace (char *) aString.
I assume you're calling this like
[myObj reverseString:"foobar"];
The string "foobar" here is a constant literal string. Its type should be const char *, but because C is braindead, it's char *. But it's still constant, so any attempt to modify it is going to fail.
Declaring the method as taking char[] actually makes no difference whatsoever. When used as a parameter type, char[] is identical to char*.
You have two choices here. The first is to duplicate the string before passing it to the method. The second is to change the method to not modify its input string at all but instead to return a new string as output. Both can be accomplished using strdup(). Just remember that the string returned from strdup() will need to be free()'d later.

How to modify unary operators in OCaml?

In OCaml, it is very easy to access to a binary operator, such as "+":
# (+);;
( + ) : int -> int -> int
And modify them as I wish:
# let (+) = (+.);;
( + ) : float -> float -> float
In the Pervasives documentation, it says that (~-) is the unary operator corresponding to (-), meaning that ~-5 returns - :int = -5.
It is easy to modify (~-) as well:
let (~-) = (~-.);;
(~-) : float -> float
Fortunately, OCaml allows the user to use (-) as an alias for (~-):
Suppose we have defined
foo : int -> int -> int
We can call
foo 1 (-1);;
which is way better than
foo 1 (~-1);;
Well, the problem is, when I change (~-) definition, it doesn't affect the unary operator (-)...
let (~-) x = 5;;
~-2;;
- : int = 5
-2;;
- : int = -2
Any idea how to modify the unary (-) as well ?
As you said, unary (-) is a shortcut for (~-). Actually, your change has affected unary (-); for example, you have many ways to use (-) as you want after overriding (~-):
# - (2+0);;
- : int = 0
# let a = 2;;
val a : int = 2
# -a;;
- : int = 0
So it works when you pass an expression to (-). In case you call -2, it will be parsed as a value, not a function application. It makes sense to follow the normal convention of negative numbers.
BTW, I don't recommend you to use this way of overriding operators. Since you have change (-) for any datatype having that operator, it may lead to confusion and strange bugs.
Here's a code extract from the compiler that seems to handle this case. Note that it only works for floating point constants. It's not a general feature of the - operator.
signed_constant:
constant { $1 }
| MINUS INT { Const_int(- $2) }
| MINUS FLOAT { Const_float("-" ^ $2) }
| MINUS INT32 { Const_int32(Int32.neg $2) }
| MINUS INT64 { Const_int64(Int64.neg $2) }
(You'll find this code in parser.mly.)
I don't think there's a way to get what you want without hacking on the compiler at this spot.

Compilation Errors on .at(i) but not on [i]

Why is it that:
char SourceChar = Text.c_str()[Index];
compiles, but
char SourceChar = Text.c_str().at(Index);
does not? Is there a workaround to this?
Text.c_str() returns a 'const char *' which is a C type, so it's not an object. You can only access it's value with Text[i] or *(Text + i).
If you want to access the i-th character in a more OOP manner you could use Text[i] or Text.at(i).

C preprocessor on Mac OSX/iPhone, usage of the '#' key?

I'm looking at some open source projects and I'm seeing the following:
NSLog(#"%s w=%f, h=%f", #size, size.width, size.height)
What exactly is the meaning of '#' right before the size symbol? Is that some kind of prefix for C strings?
To elaborate on dirkgently's answer, this looks like the implementation of a macro that takes an NSSize (or similar) argument, and prints the name of the variable (which is what the # is doing; converting the name of the variable to a string containing the name of the variable) and then its values. So in:
NSSize fooSize = NSMakeSize(2, 3);
MACRO_NAME_HERE(fooSize);
the macro would expand to:
NSLog(#"%s w=%f h=%f", "fooSize", fooSize.width, fooSize.height);
and print:
fooSize w=2.0 h=3.0
(similar to NSStringFromSize, but with the variable name)
The official name of # is the stringizing operator. It takes its argument and surrounds it in quotes to make a C string constant, escaping any embedded quotes or backslashes as necessary. It is only allowed inside the definition of a macro -- it is not allowed in regular code. For example:
// This is not legal C
const char *str = #test
// This is ok
#define STRINGIZE(x) #x
const char *str1 = STRINGIZE(test); // equivalent to str1 = "test";
const char *str2 = STRINGIZE(test2"a\""); // equivalent to str2 = "test2\"a\\\"";
A related preprocessor operator is the token-pasting operator ##. It takes two tokens and pastes them together to get one token. Like the stringizing operator, it is only allowed in macro definitions, not in regular code.
// This is not legal C
int foobar = 3;
int x = foo ## bar;
// This is ok
#define TOKENPASTE(x, y) x ## y
int foobar = 3;
int x = TOKENPASTE(foo, bar); // equivalent to x = foobar;
Is this the body of a macro definition? Then the # could be used to stringize the following identifier i.e. to print "string" (without the codes).