I'm new to Scala and a bit perplexed. While going through "Scala for the Impatient," and doing the exercises, I tried one where the result is the product of all the numeric values of the string "Hello". My first thought was to do the following:
"Hello".foldLeft(1)(_.toLong * _.toLong)
However, the expression (_.toLong * _.toLong) results in a type mismatch between the operator and the operand, an Int was expected, but it received a Long.
The following works, though:
"Hello".map(_.toLong).reduce(_ * _)
Why does the operator '*' expect an Int instead of a Long when using foldLeft? Is it because of the list's contents? Are the characters implicitly converted to Ints?
Thanks!
(Promoting my comment to an answer so the question can be closed.)
This is because your initial argument, 1, has type Int. You can resolve this by changing it to 1L.
Related
The following simple code converts an Integer value to a string value and logs it.
module Main where
import Effect (Effect)
import Effect.Console (log)
import Prelude ((<>), Unit, discard)
import Data.Int (toStringAs, radix)
type CustomerFeedback = {
customerServiceScore :: Int,
productQualityScore :: Int,
onTimeDeliveryScore :: Int
}
feedback :: CustomerFeedback
feedback = {
customerServiceScore : 4,
productQualityScore : 2,
onTimeDeliveryScore : 6
}
stringifyCustomerFeedback :: CustomerFeedback -> String
stringifyCustomerFeedback feedback = "Service: " <> toStringAs (radix 10) feedback.customerServiceScore
main ∷ Effect Unit
main = do
log (stringifyCustomerFeedback(feedback))
However, running this code produces the following error:
Could not match type
Maybe Radix
with type
Radix
while checking that type Maybe Radix
is at least as general as type Radix
while checking that expression radix 10
has type Radix
in value declaration stringifyCustomerFeedback
Questions would be as follows:
How do you change the code above so it outputs a string as expected and not an error?
What's the point of a Maybe Radix type if using it where you would use a Radix causes an error? How do you use a Maybe value?
The idea of the radix function is that you give it a number and it creates a Radix from it. But not every number constitutes a valid Radix. For example, if you give it -5, it shouldn't work. And neither should 0 or 1 for example. For some technical reasons, radices above 32 are also deemed invalid.
So that's why it returns Maybe: it would be Nothing in case the number you gave it wasn't a "valid" radix.
And the use case for that function is when you don't actually know the number ahead of time. Like if you get it from the user. Or from some sort of config file or whatnot. In that case, if you get a Nothing, you would interpret that as "invalid user input" or "corrupted config file" and report an error accordingly. And you won't even get as far as calling toStringAs. This is one of the big selling points of static types: applied properly, they can force you to write a correct, reliable program, without ignoring edge cases.
However, in case you already know that you're interested in decimal radix, just use decimal. It's a Maybe-free constant provided by the library, along with some other frequently used ones, such as binary and octal.
stringifyCustomerFeedback feedback = "Service: " <> toStringAs decimal feedback.customerServiceScore
I'm new to Scala. I'm trying to create a test case for a simple factorial function.
I couldn't assign the result value in the assert statement. I'm getting
Integer number is out of range even for type Long error in IntelliJ.
test("Factorial.factorial6") {
assert(Factorial.factorial(25) == 15511210043330985984000000L)
}
I also tried to assign the value to val, using the 'L' literal, again it shows the same
message.
val b: BigInt = 15511210043330985984000000L
I'm clearly missing some basic stuff about Scala, I would appreciate your help, to solve this
The value you are giving is indeed larger than can be held in a Long, and that is the maximum size for a literal value in Scala. However you can initialise a BigInt using a String containing the value:
val b = BigInt("15511210043330985984000000")
and therefore
assert(Factorial.factorial(25) == BigInt("15511210043330985984000000"))
This code fails:
let element: Float = self.getElement(row: 1, column: j)
let multiplier = powf(-1, j+2)*element
with this error:
Playground execution failed: :140:51: error: cannot invoke '*' with an argument list of type '(Float, Float)'
let multiplier = powf(-1, j+2)*element
Bear in mind that this occurs in this block:
for j in 0...self.columnCount {
where columnCount is a Float. Also, the first line does execute and so the getElement method indeed returns a Float.
I am completely puzzled by this as I see no reason why it shouldn't work.
There is no implicit numeric conversion in swift, so you have to do explicit conversion when dealing with different types and/or when the expected type is different than the result of the expression.
In your case, j is an Int whereas powf expects a Float, so it must be converted as follows:
let multiplier = powf(-1, Float(j)+2)*element
Note that the 2 literal, although usually considered an integer, is automatically inferred a Float type by the compiler, so in that case an explicit conversion is not required.
I ended up solving this by using Float(j) instead of j when calling powf(). Evidently, j cannot be implicitly converted to a Float.
Hi I am studying the scala language and have a question. I am reading a book and one of the example says that 0 to 2 is same as (0).to(2). How can I interpret this syntax?? I mean, I can see that to is a function that takes one integer value as its parameter. But what is "(0)." part?? Thanks
In scala any method taking a single parameter can be written with infix syntax.
So for instance if you have
class Foo(x: Int) {
def add(y: Int) = x + y
}
val a = new Foo(42)
then these two method calls are exactly equivalent
a.add(4) // 46
a add 4 // 46
The reason why there's a parenthesis around the 0 is that in older versions of scala the 0. would have been interpreted as a floating point number, due to the ambiguous value of . (which can be both a decimal separator and a method selector). Since scala 2.11 (or 2.10, I don't remember), this has been fixed, so you can now safely type
0.+(2) // Int: 2
and get an Int back, whereas you would have had a Float in the past, as the compiler would have seen it as
0.0 + (2) // Float: 2
I mean, I can see that to is a function that takes one integer value as its parameter.
No, it's not a function, it's a method.
Methods are invoked by sending a message to an object:
foo.bar(baz)
This means "send the message bar with the object referenced by baz as argument to the object referenced by foo. This will in turn cause the method bar in foo's class or one of its ancestors to be invoked.
So, to is the message, 2 is the argument, and 0 is the receiver of the message.
Scala allows you to use either a . or whitespace for message sending:
foo bar(baz)
// is the same as
foo.bar(baz)
Also, when using whitespace for message sending, you can leave off the parentheses of the last argument list if it has only a single argument:
foo bar baz
// is the same as
foo bar(baz)
And lastly, parentheses are not only used for argument lists, they are also used for grouping. (And tuple literals as well.) You can always surround an expression with parentheses to clarify its precedence:
(foo).bar(baz)
// is the same as
foo.bar(baz)
Here I tried to insert a value in GLKVector2Add value but the error comes expected expression missing in this line.
GLKVector2 self.position = GLKVector2Add({-200.695, 271},{-803.695, 0}); //Error - Expected expression
Try creating "GLKVector2" variables, setting them and then passing those as arguments in your call to "GLKVector2Add". It may be that the compiler simply doesn't know what to do with "{-200.695,271}" (a mix of float and integer numbers).
You must add them using GLKVector2Make.
So, your code will be:
GLKVector2 position = GLKVector2Add(
GLKVector2Make(-200.695, 271),
GLKVector2Make(-803.695, 0));