line width
fill
nil
|
nil
|
scala> def f(x:Int)=x*x f: (Int)Int scala> var t:(Int)=>Int=f t: (Int) => Int = <function>We can also perform such an assignment as follows
scala> var t:Function[Int, Int]=f t: (Int) => Int = <function>
val y:Function2[Int,Int,Int]=(i:Int,j:Int)=>i+j y: (Int, Int) => Int = <function>
package scala Trait Function1[T,F] { def apply(x:T):F }A function object of type (T) => F is an instance of subclass of Function1[T,F]
class FunClass extends Function[Int,Int] { def apply(x:Int):Int=x*x } defined class f
scala> val newFun=new FunClass() newFun: FunClass = <function> scala> newFun.apply(9) res1: Int = 81This is same as
scala> newFun(9) res2: Int = 81Now let us create an anonymous function
scala> val f= new Function[Int,Int] { | def apply(x:Int)=x*x | } scala> f(9) res2: Int = 81
scala> def f(x:Int)=x*x f: (Int)Int scala> f.apply(9) <console>:6: error: missing arguments for method f in object $iw; follow this method with `_' if you want to treat it as a partially applied function f.apply(9) ^Why we could not call apply() of object f? No its not. f is not a function object here. Now look back to our first try
scala> var t:Function[Int, Int]=f t: (Int) => Int = <function>Here a function object corresponds to f is generated which is an "anonymous function object" and is assigned to variable t while executing these kind of assignment statements. Here it is a simple definition for "eta expansion".
We can use Type parameter like followsscala> class g(val x:Int, val y:Int) defined class g
scala> class g[T](val x:T, val y:T)
defined class g
scala> val obj=new g[Char]('a','b')
obj: g[Char] = g@a53564
scala> obj.x
res11: Char = a
scala> obj.y
res12: Char = b
Now we can play a bitscala> val obj=new g('a','b') obj: g[Char] = g@a53564 scala> obj.x res3: Char = a
scala> val obj1=new g(1,2) obj1: g[Int] = g@a53564 scala> obj1.y res3: Char = 2
scala> val obj=new g(1,true)
obj: g[AnyVal] = g@11d95
scala> obj.x
res1: AnyVal = 1
scala> obj.y
res2: AnyVal = true
Notice that val obj=new g(1,true) doesn't cause a type mismatch error even Value 1 is of type Int and true is of Boolean while both parameters are expected to be of same type. The reason is that, Boolean, Char, Int etc. are Subtypes of AnyValue.Here The compiler inferred the type as AnyValue looking at the parameters passed.scala> class g[T,H](val x:T, val y:H)
defined class g
scala> val obj=new g('A',9)
obj: g[Char,Int] = g@14f7121
scala> obj.x
res10: Char = A
scala> obj.y
res11: Int = 9
We can define functions of parameterized type like followsscala> def f[T](x:T):Unit=print(x)
f: [T](T)Unit
scala> f[Int](6)
6
scala> f(6)
6
scala> f("ssss")
ssss
>>> def square(x):
... return x*x
and we have to make a generalized function which accepts functions of the above kind as arguments and produce new function which do some further maping. take a doubling method for now.>>> def double(x):
... return x*2
Now let us make a function mofifier function >>> def modify(f):
... def g(x):
... return double(f(x))
... return g
now we can have a new function which performs the two mappings squaring and doubling together >>> newFun=modify(square)
>>> newFun(2)
8
we can generalize the use of such function modifying functions with concept of decorators as>>> @modify
... def square(x):
... return x*x
now we have a modified version of function square(x)>>> square
<function g at 0x93dc64c>
>>> square(2)
8
Just after defining the function square, it is passed to modify() and the result returned is used instead of square().Here function decGenerator(mappingFunction) returns a function makung functio modify(f) which can be used as decorator>>> def decGenerate(mapping): ... def modify(f): ...
def g(x): ... return mapping(f(x)) ... return g ... return modify ... >>> @
decGenerate
(double) ... def square(x): ... return x*x ... >>> square(2) 8
And an object instantiation is done by>>> class myClass: ... def __init__(self,value): ... self.value=value ... print 'object initialized'
>>> a=myClass(10) object initialized >>> b=myClass(20) object initializedThis seems usual but the magic is in evaluating the function myClass(value). an expression in the formmyClass(args) causes a call to __init__(self,args) defined inside class myClass.
>>> c=myClass(a.value+b.value) object initialized >>> c.value 30It will be awesome if we can perform
>>> c=a+b object initialized >>> c.value 30We can make this possible by including a magic function __add__ to the class definition of myClass.
>>> class myClass: ... def __init__(self,value): ... self.value=value ... print 'object initialized' ... def __add__(self,obj): ... c=myClass(self.value+obj.value) ... return cHere c=a+b is evaluated as c=a.__add__(b)
Operator | Special method |
- | __sub__(self, other) |
// | __floordiv__(self, other) |
/ | __div__(self, other) |
% | __mod_(self, other) |
** | __pow__ |
<< | __lshift__(self, other) |
& | __and__(self, other) |
| | __or__(self, other) |
^ | __xor__(self, other) |
>>> class mysequance: ... def __init__(self,list): ... self.value=list ... def __iter__(self): ... return iter(self.value) ... def __getitem__(self,index): ... return self.value[index] ... def __len__(self): ... return len(self.value) ... >>> s=mysequance([1,2,3,4,5,6])
>>> len(s) 6 >>> s[1] 2 >>> it=iter(s) >>> for i in it: ... print i ... 1 2 3 4 5 6
>>> list=[1,2,3,4]
>>> lit=iter(list)
>>> lit
<listiterator object at 0x96abd2c>
>>> lit.next()
1
>>> lit.next()
2
>>> lit.next()
3
>>> lit.next()
4
>>> lit.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> tit=iter((1,2,3,4))
>>> tit
<tupleiterator object at 0x96abfcc>
>>> 3 in tit
True
>>> def listgen(n):
... for i in range(n):
... yield i
...
>>> g=listgen(5)
>>> g
<generator object listgen at 0xb786af7c>
>>> g=listgen(3)
>>> g.next()
0
>>> g.next()
1
>>> g.next()
2
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
squares=[i*i for i in range(10) if i%2==1]
>>> squares
[1, 9, 25, 49, 81]
>>> squares=[]
>>> for i in range(10):
... if i%2==1:
... squares.append(i*i)
...
>>>squares=map((lambda x: x*x),filter((lambda x:x%2==1), range(10)))
>>> matrix=[[1,2,3],[4,5,6],[7,8,9]]
>>> transpose=[[matrix[i][j] for i in range(len(matrix))] for j in range(len(matrix[0]))]
>>> transpose
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
>>> class term:
def __init__(self,a,d):
self.value=a
self.d=d
def next(self):
self.value+=self.d
return self
>>> x=term(1,2)
Here x is capable of generating terms in an arithmetic progression with a=0 and common difference d=2, as follows.
>>> x.next()
>>> x.value
3
>>> x.next()
>>> x.value
5
>>> x.next()
>>> x.value
7
We can perform such an abstraction with functional programming facilities as follows.>>> def term(a,d):
... return(lambda f: f(a,d))
...
>>> def next(s):
... return s(lambda a,d: term(a+d,d))
...
>>> def value(s):
... return s(lambda a,b:a)
...
>>> x=term(1,2)
>>> value(x)
1
>>> x=next(x)
>>> value(x)
3
>>> value(next(next(next(next(term(1,2))))))
9
Inside term(a,b) a nameless function is defined using lambda expression. The definition of this lambda function contain use of local variables of function term(). The closure property of functional languages facilitate this kind of definition of functions inside a function. Again, this lambda function accepts a function f of the form
f(a,b):
return expression_on(a,b)
>>>x.next().value==x.next().value
False
in second case>>>value(next(x))==
value(next(x)
) True