+ is a method.
5 + 3 #=> 8
5.+(3) #=> 8
Can anyone show me the method definition of +?
Here's the source of Integer#+ for 2.5.0:
VALUE
rb_int_plus(VALUE x, VALUE y)
{
if (FIXNUM_P(x)) {
return fix_plus(x, y);
}
else if (RB_TYPE_P(x, T_BIGNUM)) {
return rb_big_plus(x, y);
}
return rb_num_coerce_bin(x, y, '+');
}
It's usually easy to find it in documentation:
https://ruby-doc.org/core-2.5.0/Integer.html#method-i-2B
Keep in mind what Jörg W Mittag pointed out - there are number of + methods and for example method + defined on what's returned by 4.4 literal will differ, because it's Float, not Integer.
You also may have noticed that it's C, not Ruby. It's because Ruby interpreter, MRI, is written in C, so no wonder that the core functions of this language (like Integer class and its methods) are also written in C.
Just for your information, there is a gem that provides documentation/source code for Ruby in shell : pry-doc
It is a plug-in for pry (another ruby shell)
It's very useful and helped me every day. I really recommend it for any ruby project.
Your case is pretty particular and gave me a headache trying to get the + method source. I learned that when looking for operator (+, -, ==, <<, ...) source code or documentation, you have to put a . in front the operator.
Example
pry(main)> ? [].==
From: array.c (C Method):
Owner: Array
Visibility: public
Signature: ==(arg1)
Number of lines: 7
Equality --- Two arrays are equal if they contain the same number of elements and if each element is equal to (according to Object#==) the corresponding element in other_ary.
[ "a", "c" ] == [ "a", "c", 7 ] #=> false
Below is how to use it in your case
[1] pry(main)> x = 5
=> 5
[2] pry(main)> show-source x.+
From: numeric.c (C Method):
Owner: Integer
Visibility: public
Number of lines: 11
VALUE
rb_int_plus(VALUE x, VALUE y)
{
if (FIXNUM_P(x)) {
return fix_plus(x, y);
}
else if (RB_TYPE_P(x, T_BIGNUM)) {
return rb_big_plus(x, y);
}
return rb_num_coerce_bin(x, y, '+');
}
[3] pry(main)> x = 5.0
=> 5.0
[4] pry(main)> $ x.+
From: numeric.c (C Method):
Owner: Float
Visibility: public
Number of lines: 16
static VALUE
flo_plus(VALUE x, VALUE y)
{
if (RB_TYPE_P(y, T_FIXNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y));
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) + rb_big2dbl(y));
}
else if (RB_TYPE_P(y, T_FLOAT)) {
return DBL2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y));
}
else {
return rb_num_coerce_bin(x, y, '+');
}
}
Here is the implementation in Opal:
def +(other)
%x{
if (other.$$is_number) {
return self + other;
}
else {
return #{__coerced__ :+, other};
}
}
end
You may have noticed that it is Ruby with embedded ECMAScript which in turn has Ruby embedded in it. Opal is a compiler for the ECMAScript platform, so some low-level methods are partially implemented in ECMAScript for performance reasons.
Related
I am getting my head around the functional model in Ruby and ran into a problem. I am able to successfully pass any given number of arguments to an arbitrary function as follows:
add = ->(x, y) { return x + y }
mul = ->(x, y) { return x * y }
def call_binop(a, b, &func)
return func.call(a, b)
end
res = call_binop(2, 3, &add)
print("#{res}\n") #5
res = call_binop(3, 4, &mul)
print("#{res}\n") #12
However, I am not able to pass an arbitrary number of functions:
dbl = ->(x) { return 2 * x }
sqr = ->(x) { return x * x }
def call_funccomp(a, &func1, &func2)
return func2.call(func1.call(a))
end
res = call_funccomp(3, &dbl, &sqr)
print("#{res}\n") #Expect 36 but compiler error
The compiler error is syntax error, unexpected ',', expecting ')'
I have already added both lambdas and procs to an array and then executed elements of the array, so I know I can get around this by passing such an array as an argument, but for simple cases this seems to be a contortion for something (I hope) is legal in the language. Does Ruby actually limit the number or lambdas one can pass in the argument list? It seems to have a reasonably modern, flexible functional model (the notation is a little weird) where things can just execute via a call method.
Does Ruby actually limit the number or lambdas one can pass in the argument list?
No, you can pass as many procs / lambdas as you like. You just cannot pass them as block arguments.
Prepending the proc with & triggers Ruby's proc to block conversion, i.e. your proc becomes a block argument. And Ruby only allows at most one block argument.
Attempting to call call_funccomp(3, &dbl, &sqr) is equivalent to passing two blocks:
call_funccomp(3) { 2 * x } { x * x }
something that Ruby doesn't allow.
The fix is to omit &, i.e. to pass the procs / lambdas as positional arguments:
dbl = ->(x) { 2 * x }
sqr = ->(x) { x * x }
def call_funccomp(a, func1, func2)
func2.call(func1.call(a))
end
res = call_funccomp(3, dbl, sqr)
print("#{res}\n")
There's also Proc#>> which combines two procs:
def call_funccomp(a, func1, func2)
(func1 >> func2).call(a)
end
In the code below, I want to retain number_list, after iterating over it, since the .into_iter() that for uses by default will consume. Thus, I am assuming that n: &i32 and I can get the value of n by dereferencing.
fn main() {
let number_list = vec![24, 34, 100, 65];
let mut largest = number_list[0];
for n in &number_list {
if *n > largest {
largest = *n;
}
}
println!("{}", largest);
}
It was revealed to me that instead of this, we can use &n as a 'pattern':
fn main() {
let number_list = vec![24, 34, 100, 65];
let mut largest = number_list[0];
for &n in &number_list {
if n > largest {
largest = n;
}
}
println!("{}", largest);
number_list;
}
My confusion (and bear in mind I haven't covered patterns) is that I would expect that since n: &i32, then &n: &&i32 rather than it resolving to the value (if a double ref is even possible). Why does this happen, and does the meaning of & differ depending on context?
It can help to think of a reference as a kind of container. For comparison, consider Option, where we can "unwrap" the value using pattern-matching, for example in an if let statement:
let n = 100;
let opt = Some(n);
if let Some(p) = opt {
// do something with p
}
We call Some and None constructors for Option, because they each produce a value of type Option. In the same way, you can think of & as a constructor for a reference. And the syntax is symmetric:
let n = 100;
let reference = &n;
if let &p = reference {
// do something with p
}
You can use this feature in any place where you are binding a value to a variable, which happens all over the place. For example:
if let, as above
match expressions:
match opt {
Some(1) => { ... },
Some(p) => { ... },
None => { ... },
}
match reference {
&1 => { ... },
&p => { ... },
}
In function arguments:
fn foo(&p: &i32) { ... }
Loops:
for &p in iter_of_i32_refs {
...
}
And probably more.
Note that the last two won't work for Option because they would panic if a None was found instead of a Some, but that can't happen with references because they only have one constructor, &.
does the meaning of & differ depending on context?
Hopefully, if you can interpret & as a constructor instead of an operator, then you'll see that its meaning doesn't change. It's a pretty cool feature of Rust that you can use constructors on the right hand side of an expression for creating values and on the left hand side for taking them apart (destructuring).
As apart from other languages (C++), &n in this case isn't a reference, but pattern matching, which means that this is expecting a reference.
The opposite of this would be ref n which would give you &&i32 as a type.
This is also the case for closures, e.g.
(0..).filter(|&idx| idx < 10)...
Please note, that this will move the variable, e.g. you cannot do this with types, that don't implement the Copy trait.
My confusion (and bear in mind I haven't covered patterns) is that I would expect that since n: &i32, then &n: &&i32 rather than it resolving to the value (if a double ref is even possible). Why does this happen, and does the meaning of & differ depending on context?
When you do pattern matching (for example when you write for &n in &number_list), you're not saying that n is an &i32, instead you are saying that &n (the pattern) is an &i32 (the expression) from which the compiler infers that n is an i32.
Similar things happen for all kinds of pattern, for example when pattern-matching in if let Some (x) = Some (42) { /* … */ } we are saying that Some (x) is Some (42), therefore x is 42.
A generic method that can return a random integer between 2 parameters like ruby does with rand(0..n).
Any suggestion?
My suggestion would be an extension function on IntRange to create randoms like this: (0..10).random()
TL;DR Kotlin >= 1.3, one Random for all platforms
As of 1.3, Kotlin comes with its own multi-platform Random generator. It is described in this KEEP. The extension described below is now part of the Kotlin standard library, simply use it like this:
val rnds = (0..10).random() // generated random from 0 to 10 included
Kotlin < 1.3
Before 1.3, on the JVM we use Random or even ThreadLocalRandom if we're on JDK > 1.6.
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
Used like this:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
If you wanted the function only to return 1, 2, ..., 9 (10 not included), use a range constructed with until:
(0 until 10).random()
If you're working with JDK > 1.6, use ThreadLocalRandom.current() instead of Random().
KotlinJs and other variations
For kotlinjs and other use cases which don't allow the usage of java.util.Random, see this alternative.
Also, see this answer for variations of my suggestion. It also includes an extension function for random Chars.
Generate a random integer between from(inclusive) and to(exclusive)
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
As of kotlin 1.2, you could write:
(1..3).shuffled().last()
Just be aware it's big O(n), but for a small list (especially of unique values) it's alright :D
In Kotlin SDK >=1.3 you can do it like
import kotlin.random.Random
val number = Random.nextInt(limit)
You can create an extension function similar to java.util.Random.nextInt(int) but one that takes an IntRange instead of an Int for its bound:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
You can now use this with any Random instance:
val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, 8, or 9
If you don't want to have to manage your own Random instance then you can define a convenience method using, for example, ThreadLocalRandom.current():
fun rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Now you can get a random integer as you would in Ruby without having to first declare a Random instance yourself:
rand(5..9) // returns 5, 6, 7, 8, or 9
Possible Variation to my other answer for random chars
In order to get random Chars, you can define an extension function like this
fun ClosedRange<Char>.random(): Char =
(Random().nextInt(endInclusive.toInt() + 1 - start.toInt()) + start.toInt()).toChar()
// will return a `Char` between A and Z (incl.)
('A'..'Z').random()
If you're working with JDK > 1.6, use ThreadLocalRandom.current() instead of Random().
For kotlinjs and other use cases which don't allow the usage of java.util.Random, this answer will help.
Kotlin >= 1.3 multiplatform support for Random
As of 1.3, Kotlin comes with its own multiplatform Random generator. It is described in this KEEP. You can now directly use the extension as part of the Kotlin standard library without defining it:
('a'..'b').random()
Building off of #s1m0nw1 excellent answer I made the following changes.
(0..n) implies inclusive in Kotlin
(0 until n) implies exclusive in Kotlin
Use a singleton object for the Random instance (optional)
Code:
private object RandomRangeSingleton : Random()
fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start
Test Case:
fun testRandom() {
Assert.assertTrue(
(0..1000).all {
(0..5).contains((0..5).random())
}
)
Assert.assertTrue(
(0..1000).all {
(0..4).contains((0 until 5).random())
}
)
Assert.assertFalse(
(0..1000).all {
(0..4).contains((0..5).random())
}
)
}
Examples random in the range [1, 10]
val random1 = (0..10).shuffled().last()
or utilizing Java Random
val random2 = Random().nextInt(10) + 1
No need to use custom extension functions anymore. IntRange has a random() extension function out-of-the-box now.
val randomNumber = (0..10).random()
Kotlin >= 1.3, multiplatform support for Random
As of 1.3, the standard library provided multi-platform support for randoms, see this answer.
Kotlin < 1.3 on JavaScript
If you are working with Kotlin JavaScript and don't have access to java.util.Random, the following will work:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
Used like this:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Another way of implementing s1m0nw1's answer would be to access it through a variable. Not that its any more efficient but it saves you from having to type ().
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
And now it can be accessed as such
(1..10).random
If the numbers you want to choose from are not consecutive, you can use random().
Usage:
val list = listOf(3, 1, 4, 5)
val number = list.random()
Returns one of the numbers which are in the list.
Using a top-level function, you can achieve exactly the same call syntax as in Ruby (as you wish):
fun rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
Usage:
rand(1, 3) // returns either 1, 2 or 3
There is no standard method that does this but you can easily create your own using either Math.random() or the class java.util.Random. Here is an example using the Math.random() method:
fun random(n: Int) = (Math.random() * n).toInt()
fun random(from: Int, to: Int) = (Math.random() * (to - from) + from).toInt()
fun random(pair: Pair<Int, Int>) = random(pair.first, pair.second)
fun main(args: Array<String>) {
val n = 10
val rand1 = random(n)
val rand2 = random(5, n)
val rand3 = random(5 to n)
println(List(10) { random(n) })
println(List(10) { random(5 to n) })
}
This is a sample output:
[9, 8, 1, 7, 5, 6, 9, 8, 1, 9]
[5, 8, 9, 7, 6, 6, 8, 6, 7, 9]
Kotlin standard lib doesn't provide Random Number Generator API. If you aren't in a multiplatform project, it's better to use the platform api (all the others answers of the question talk about this solution).
But if you are in a multiplatform context, the best solution is to implement random by yourself in pure kotlin for share the same random number generator between platforms. It's more simple for dev and testing.
To answer to this problem in my personal project, i implement a pure Kotlin Linear Congruential Generator. LCG is the algorithm used by java.util.Random. Follow this link if you want to use it :
https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
My implementation purpose nextInt(range: IntRange) for you ;).
Take care about my purpose, LCG is good for most of the use cases (simulation, games, etc...) but is not suitable for cryptographically usage because of the predictability of this method.
First, you need a RNG. In Kotlin you currently need to use the platform specific ones (there isn't a Kotlin built in one). For the JVM it's java.util.Random. You'll need to create an instance of it and then call random.nextInt(n).
To get a random Int number in Kotlin use the following method:
import java.util.concurrent.ThreadLocalRandom
fun randomInt(rangeFirstNum:Int, rangeLastNum:Int) {
val randomInteger = ThreadLocalRandom.current().nextInt(rangeFirstNum,rangeLastNum)
println(randomInteger)
}
fun main() {
randomInt(1,10)
}
// Result – random Int numbers from 1 to 9
Hope this helps.
Below in Kotlin worked well for me:
(fromNumber.rangeTo(toNumber)).random()
Range of the numbers starts with variable fromNumber and ends with variable toNumber. fromNumber and toNumber will also be included in the random numbers generated out of this.
You could create an extension function:
infix fun ClosedRange<Float>.step(step: Float): Iterable<Float> {
require(start.isFinite())
require(endInclusive.isFinite())
require(step.round() > 0.0) { "Step must be positive, was: $step." }
require(start != endInclusive) { "Start and endInclusive must not be the same"}
if (endInclusive > start) {
return generateSequence(start) { previous ->
if (previous == Float.POSITIVE_INFINITY) return#generateSequence null
val next = previous + step.round()
if (next > endInclusive) null else next.round()
}.asIterable()
}
return generateSequence(start) { previous ->
if (previous == Float.NEGATIVE_INFINITY) return#generateSequence null
val next = previous - step.round()
if (next < endInclusive) null else next.round()
}.asIterable()
}
Round Float value:
fun Float.round(decimals: Int = DIGITS): Float {
var multiplier = 1.0f
repeat(decimals) { multiplier *= 10 }
return round(this * multiplier) / multiplier
}
Method's usage:
(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }
Output:
value: 0.0 value: 0.1 value: 0.2 value: 0.3 value: 0.4 value: 0.5
value: 0.6 value: 0.7 value: 0.8 value: 0.9 value: 1.0
Full source code. Can control whether duplicates are allowed.
import kotlin.math.min
abstract class Random {
companion object {
fun string(length: Int, isUnique: Boolean = false): String {
if (0 == length) return ""
val alphabet: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9') // Add your set here.
if (isUnique) {
val limit = min(length, alphabet.count())
val set = mutableSetOf<Char>()
do { set.add(alphabet.random()) } while (set.count() != limit)
return set.joinToString("")
}
return List(length) { alphabet.random() }.joinToString("")
}
fun alphabet(length: Int, isUnique: Boolean = false): String {
if (0 == length) return ""
val alphabet = ('A'..'Z')
if (isUnique) {
val limit = min(length, alphabet.count())
val set = mutableSetOf<Char>()
do { set.add(alphabet.random()) } while (set.count() != limit)
return set.joinToString("")
}
return List(length) { alphabet.random() }.joinToString("")
}
}
}
Whenever there is a situation where you want to generate key or mac address which is hexadecimal number having digits based on user demand, and that too using android and kotlin, then you my below code helps you:
private fun getRandomHexString(random: SecureRandom, numOfCharsToBePresentInTheHexString: Int): String {
val sb = StringBuilder()
while (sb.length < numOfCharsToBePresentInTheHexString) {
val randomNumber = random.nextInt()
val number = String.format("%08X", randomNumber)
sb.append(number)
}
return sb.toString()
}
Here is a straightforward solution in Kotlin, which also works on KMM:
fun IntRange.rand(): Int =
Random(Clock.System.now().toEpochMilliseconds()).nextInt(first, last)
Seed is needed for the different random number on each run. You can also do the same for the LongRange.
Gets the next random Int from the random number generator.
Random.nextInt()
to be super duper ))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}
I've recently had a look at Haskell's Monad - State. I've been able to create functions that operate with this Monad, but I'm trying to encapsulate the behavior into a class, basically I'm trying to replicate in Haskell something like this:
class A {
public:
int x;
void setX(int newX) {
x = newX;
}
void getX() {
return x;
}
}
I would be very grateful if anyone can help with this. Thanks!
I would start off by noting that Haskell, to say the least, does not encourage traditional OO-style development; instead, it has features and characteristics that lend themselves well to the sort of 'pure functional' manipulation that you won't really find in many other languages; the short on this is that trying to 'bring over' concepts from other (traditional languages) can often be a very bad idea.
but I'm trying to encapsulate the behavior into a class
Hence, my first major question that comes to mind is why? Surely you must want to do something with this (traditional OO concept of a) class?
If an approximate answer to this question is: "I'd like to model some sort of data construct", then you'd be better off working with something like
data A = A { xval :: Int }
> let obj1 = A 5
> xval obj1
5
> let obj2 = obj1 { xval = 10 }
> xval obj2
10
Which demonstrates pure, immutable data structures, along with 'getter' functions and destructive updates (utilizing record syntax). This way, you'd do whatever work you need to do as some combination of functions mapping these 'data constructs' to new data constructs, as appropriate.
Now, if you absolutely needed some sort of model of State (and indeed, answering this question requires a bit of experience in knowing exactly what local versus global state is), only then would you delve into using the State Monad, with something like:
module StateGame where
import Control.Monad.State
-- Example use of State monad
-- Passes a string of dictionary {a,b,c}
-- Game is to produce a number from the string.
-- By default the game is off, a C toggles the
-- game on and off. A 'a' gives +1 and a b gives -1.
-- E.g
-- 'ab' = 0
-- 'ca' = 1
-- 'cabca' = 0
-- State = game is on or off & current score
-- = (Bool, Int)
type GameValue = Int
type GameState = (Bool, Int)
playGame :: String -> State GameState GameValue
playGame [] = do
(_, score) <- get
return score
playGame (x:xs) = do
(on, score) <- get
case x of
'a' | on -> put (on, score + 1)
'b' | on -> put (on, score - 1)
'c' -> put (not on, score)
_ -> put (on, score)
playGame xs
startState = (False, 0)
main = print $ evalState (playGame "abcaaacbbcabbab") startState
(shamelessly lifted from this tutorial). Note the use of the analogous 'pure immutable data structures' within the context of a state monad, in addition to 'put' and 'get' monadic functions, which facilitate access to the state contained within the State Monad.
Ultimately, I'd suggest you ask yourself: what is it that you really want to accomplish with this model of an (OO) class? Haskell is not your typical OO-language, and trying to map concepts over 1-to-1 will only frustrate you in the short (and possibly long) term. This should be a standard mantra, but I'd highly recommend learning from the book Real World Haskell, where the authors are able to delve into far more detailed 'motivation' for picking any one tool or abstraction over another. If you were adamant, you could model traditional OO constructs in Haskell, but I wouldn't suggest going about doing this - unless you have a really good reason for doing so.
It takes a bit of permuting to transform imperative code into a purely functional context.
A setter mutates an object. We're not allowed to do that directly in Haskell because of laziness and purity.
Perhaps, if we transcribe the State monad to another language it'll be more apparent. Your code is in C++, but because I at least want garbage collection I'll use java here.
Since Java never got around to defining anonymous functions, first, we'll define an interface for pure functions.
public interface Function<A,B> {
B apply(A a);
}
Then we can make up a pure immutable pair type.
public final class Pair<A,B> {
private final A a;
private final B b;
public Pair(A a, B b) {
this.a = a;
this.b = b;
}
public A getFst() { return a; }
public B getSnd() { return b; }
public static <A,B> Pair<A,B> make(A a, B b) {
return new Pair<A,B>(a, b);
}
public String toString() {
return "(" + a + ", " + b + ")";
}
}
With those in hand, we can actually define the State monad:
public abstract class State<S,A> implements Function<S, Pair<A, S> > {
// pure takes a value a and yields a state action, that takes a state s, leaves it untouched, and returns your a paired with it.
public static <S,A> State<S,A> pure(final A a) {
return new State<S,A>() {
public Pair<A,S> apply(S s) {
return new Pair<A,S>(a, s);
}
};
}
// we can also read the state as a state action.
public static <S> State<S,S> get() {
return new State<S,S>() {
public Pair<S,S> apply(S, s) {
return new Pair<S,S>(s, s);
}
}
}
// we can compose state actions
public <B> State<S,B> bind(final Function<A, State<S,B>> f) {
return new State<S,B>() {
public Pair<B,S> apply(S s0) {
Pair<A,S> p = State.this.apply(s0);
return f.apply(p.getFst()).apply(p.getSnd());
}
};
}
// we can also read the state as a state action.
public static <S> State<S,S> put(final S newS) {
return new State<S,S>() {
public Pair<S,S> apply(S, s) {
return new Pair<S,S>(s, newS);
}
}
}
}
Now, there does exist a notion of a getter and a setter inside of the state monad. These are called lenses. The basic presentation in Java would look like:
public abstract class Lens[A,B] {
public abstract B get(A a);
public abstract A set(B b, A a);
// .. followed by a whole bunch of concrete methods.
}
The idea is that a lens provides access to a getter that knows how to extract a B from an A, and a setter that knows how to take a B and some old A, and replace part of the A, yielding a new A. It can't mutate the old one, but it can construct a new one with one of the fields replaced.
I gave a talk on these at a recent Boston Area Scala Enthusiasts meeting. You can watch the presentation here.
To come back into Haskell, rather than talk about things in an imperative setting. We can import
import Data.Lens.Lazy
from comonad-transformers or one of the other lens libraries mentioned here. That link provides the laws that must be satisfied to be a valid lens.
And then what you are looking for is some data type like:
data A = A { x_ :: Int }
with a lens
x :: Lens A Int
x = lens x_ (\b a -> a { x_ = b })
Now you can write code that looks like
postIncrement :: State A Int
postIncrement = do
old_x <- access x
x ~= (old_x + 1)
return old_x
using the combinators from Data.Lens.Lazy.
The other lens libraries mentioned above provide similar combinators.
First of all, I agree with Raeez that this probably the wrong way to go, unless you really know why! If you want to increase some value by 42 (say), why not write a function that does that for you?
It's quite a change from the traditional OO mindset where you have boxes with values in them and you take them out, manipulate them and put them back in. I would say that until you start noticing the pattern "Hey! I always take some value as an argument, and at the end return it slightly modified, tupled with some other value and all the plumbing is getting messy!" you don't really need the State monad. Part of the fun of (learning) Haskell is finding new ways to get around the stateful OO thinking!
That said, if you absolutely want a box with an x of type Int in it, you could try making your own get and put variants, something like this:
import Control.Monad.State
data Point = Point { x :: Int, y :: Int } deriving Show
getX :: State Point Int
getX = get >>= return . x
putX :: Int -> State Point ()
putX newVal = do
pt <- get
put (pt { x = newVal })
increaseX :: State Point ()
increaseX = do
x <- getX
putX (x + 1)
test :: State Point Int
test = do
x1 <- getX
increaseX
x2 <- getX
putX 7
x3 <- getX
return $ x1 + x2 + x3
Now, if you evaluate runState test (Point 2 9) in ghci, you'll get back (12,Point {x = 7, y = 9}) (since 12 = 2 + (2+1) + 7 and the x in the state gets set to 7 at the end). If you don't care about the returned point, you can use evalState and you'll get just the 12.
There's also more advanced things to do here like abstracting out Point with a typeclass in case you have multiple datastructures which have something which behaves like x but that's better left for another question, in my opinion!
We've been profiling our code recently and we've come across a few annoying hotspots. They're in the form
assert(a == b, a + " is not equal to " + b)
Because some of these asserts can be in code called a huge amount of times the string concat starts to add up. assert is defined as:
def assert(assumption : Boolean, message : Any) = ....
why isn't it defined as:
def assert(assumption : Boolean, message : => Any) = ....
That way it would evaluate lazily. Given that it's not defined that way is there an inline way of calling assert with a message param that is evaluated lazily?
Thanks
Lazy evaluation has also some overhead for the function object created. If your message object is already fully constructed (a static message) this overhead is unnecessary.
The appropriate method for your use case would be sprintf-style:
assert(a == b, "%s is not equal to %s", a, b)
As long as there is a speciaized function
assert(Boolean, String, Any, Any)
this implementation has no overhead or the cost of the var args array
assert(Boolean, String, Any*)
for the general case.
Implementing toString would be evaluated lazily, but is not readable:
assert(a == b, new { override def toString = a + " is not equal to " + b })
It is by-name, I changed it over a year ago.
http://www.scala-lang.org/node/825
Current Predef:
#elidable(ASSERTION)
def assert(assertion: Boolean, message: => Any) {
if (!assertion)
throw new java.lang.AssertionError("assertion failed: "+ message)
}
Thomas' answer is great, but just in case you like the idea of the last answer but dislike the unreadability, you can get around it:
object LazyS {
def apply(f: => String): AnyRef = new {
override def toString = f
}
}
Example:
object KnightSpeak {
override def toString = { println("Turned into a string") ; "Ni" }
}
scala> assert(true != false , LazyS("I say " + KnightSpeak))
scala> println( LazyS("I say " + KnightSpeak) )
Turned into a string
I say Ni
Try: assert( a==b, "%s is not equals to %s".format(a,b))
The format should only be called when the assert needs the string. Format is added to RichString via implicit.