Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
]`W_^%7N35 *6―=��35c�/d�.&�0―
���-
�'!
�X_U[Qe2015�#;�� �'!>]`W_^%7N35,?O�KALe$21P�8PSNOe�41c��dB�+� FLARGf�X_U[O6T,B@JH��OQe��P�:Q�41O@TRGPMD"�CIEAf
2016�#;��e���-
�<X_U[PDFc� (9\YZabV)HP/��dhttp://www-ikn.ist.hokudai.ac.jp/~arim/pub/proriron/
,/'.-��$��
n 1940s-1950s ��: ��� &(0+.n 1960s: FORTRAN, LISP, ALGOL2PASCAL3n 1970s: C��n 1980s: C++, Objective C, SmallTalk n 1990s: Javan Perl, Python, Ruby, ... , Scala, Haskell
n �2�#� ���3– ��� 2Scala, Haskel, java$lambda3– ���2Scala%SML$���3
– �������"���2*1)�����3
��!�
� �
�����
n 学ぶこと‒ 関数型プログラミング‒ 自然数に対する関数の帰納的定義‒ リスト処理‒ リストに対する関数の帰納的定義‒ Scala言語を使ってみよう
n プログラム‒ 自然数: • 足し算plus, 掛け算times
‒ リスト処理• リストの要素の総和• 二つのリストの連結• リストの反転:ふつう版と高速版
����������������
���������
�� ���������
n �(basis'��#�����#�������#��&���(Constructor)� "!$#��� "��%���#– �(�� • 0������• x �������x�1 ����������
• ����2������������������ �����
���
�����*�
n �����)-.���*��N– N+�����*��&��&��"/.
• 0�������0ÎN• x ������x�1������������1����(s)�N→N ��������������������
n ��– Inductive set N with
0:Ns1N→N
n ���*��– 0,s(0),s(s(0)),s(s(s(0))),....– s*�0�����)���.'���� �$%�.���*
� '�# (.
�,!
����/��
n ���+�46)���+/��– is_080(��)+ *)#-!#7�15��– y¹0/���(yÎN) .0�� �7��'5�/���$��'50(+ 58s(x)=y
– &&+�� �7��'5�/���7�35��7s-
1(y)=x,��'5�• s-1(0)��������• s-1(s(x))=x, s (s-1(x))=x
"2%
���/���#%'����
n ���/���).-,*+"��� �)���"#%&���)��
n �������!��('– �0� �
plus(x,y) = if is_0(x) then y else s(plus(s-1 (x),y))
– ���0• plus(s(s(0)), s(s(s(0))))
s(plus(s-1 (s(s(0))), s(s(s(0)))))s(plus(s(0), s(s(s(0)))))s(s(plus(s-1(s(0)), s(s(s(0))))))s(s(plus(0, s(s(s(0))))))s(s(s(s(s(0)))))
�$�
� ��
n ���"(����times(x,y)(����times(s(s(0),s(s(0)))(��&�
n �� �'#��!����plus(x,y)(����%���
�$�
�����
��� ����
����JQS^X\��
n ^X\GL
6 ��K[`Yb��cK�M
6 �c %�#��+ �, �- �.��Ld��+ �, �- �.�:�J�UB^X\e
6 ��JQCELdW_]T��>E �+�,�-�.cGO�8ARb%$('��IHcd��VZWTD9CE )+ �, �- �.*�G�;<GO7Sb'54/32ce
n �^X\f���!K��I^X\6 ��P&01F�?bNALGO9;e��I>F��9C<)G*T
�;c
n ^X\K�=f @K��K�n �c �K^X\%K�=L"
<<L�a
/-.' +� �
n x = first(L) :/-.L(��(��– ��first(0 1 2 3) = 0
n M = rest(L) :/-.L(�*(��– ��rest(0 1 2 3) = (1 2 3)– ������firstrest��� ��� �
n L = cons(x, M) : ���#!/-.M(��'��x,��!/-.L,� 1– ��L3 = cons(3, nil) =(3), L2 = cons(2, L3)= (2, 3),
L1 = cons(1, L2) = (1, 2, 3)n is_nil(L) : /-.L�0�/-.(nil)�2
– ��is_nil(nil) = true, is_nil((1 2))= false, is_nil(1)= false
��"�&($��'....
�%$Scala��$��,�)
LEG7 1=%�8��
n �-8IMDKJND��*9Q�:!:%�503LEG8��%�@;23*=
– length(L) = LEGL8$/O���P– sum(L) = �8LEGL8��8��– append(X, Y) = LEGX5LEGY8"�– reverse(L) = LEGL8�
n .><@��4�*3:=.59Q%���8�*��&
– ���9�?6*.5R– #�ACFE9�?6*.5
�*P .8EKBH8��+4,=IMDKJND��: )scala, (LISP, scheme, Haskell. 'Python, Ruby
�*)'(� "���
n )'(� !�#%$��"�"��&��
n ���• sum((1 2 3)) = 1 + sum((2 3))
= 1 + 2 + sum((3))= 1 + 2 + 3 + sum(nil)= 1 + 2 + 3 + 0= 6
sum(x) = if is_nil(x) then 0 else first(x)+ sum(rest(x))
���� "���!....
���Scala����&�#�
�'&$%���
n &$%���� "!����#�
n � ��• length((1 2 3)) = 1 + length ((2 3))
= 1 + 1 + length ((3))= 1 + 1 + 1 + length (nil)= 1 + 1 + 1 + 0= 3
length(x) = if is_nil(x) then 0 else 1+ length(rest(x))
���Scala�����#� �
���������....
�$#!"��
n 2�����#!" �
n ����• append((1 2 3), (4 5))
= cons(1, append((2 3), (4 5)))= cons (1, cons(2, append((3), (4 5)))) = cons (1, cons(2, cons(3, append(nil, (4 5))))) = cons (1, cons(2, cons(3, (4 5))))= cons (1, cons(2, (3 4 5)))= cons (1, (2 3 4 5))= (1 2 3 4 5)
append(x, y) = if is_nil(x) then y else cons((first(x), append(rest(x), y))
���Scala ���� ���
���������....
����
SCALA���������� ����
�����
Scala���7$3 (1)n Scala��
– �K�'�75)!4����-�(– ��&1:B=9;@-��0�#4– 8G?CE?IREPLFHCJ*KJava����IJVMJ /-<GA8D-��%�#4
n ��- �. "�� : "-2",�'Ln �J x : Int, y : String
n !6!6+% 4
n Int ��
n String ���
n List[Int] ��-E>@I��J
scala���
scala����M. Odersky��� �����������791pages�
Martin Odersky• EPFL�Ecole Poly-
technique Fedele de Lausanne����
• ���Java������javac����
• scala����
Scala&(�I1G (2)
n ��@�0>���&7H
n val x ��:3=/��?�&[B90\
n var x �� %=��?�&[�I=/\
n ,��&[�#3�&\@ "def":�$7H^n 1F->],��]��;�?�A]*G�?�?->�3]"="?.;>,�?��J�4^
n �\ def add(x : Int, y : Int) : Int = { x + y }n �+�SXLVUYL[�#3"&(\?C;K<?���JE9
n �\ if-then-else�, while�n RNZYTPO�[match-case�\:]if�?�IG>���52:3H^[WMQ�!>��\
2016.12.22: ,��&?�?)GJ' 6D68^
Scala$)�(&����+scala��,
arim@lecture$ scalaWelcome to Scala 2.11.8(Java HotSpot(TM) 64-Bit ....
scala> val msg = "hello world!"msg: String = hello world!
scala> val x = 2 + 3x: Int = 5
scala> :quitarim@material$
�x�Int�+�,
�msg�String�+����,
unix/linux��%*#(�*��scala�%*#���
scala�!" '*� �
val�������������
Scala���� ����scala���
scala> def add(x : Int, y : Int) : Int = x + yadd: (x: Int, y: Int)Int
scala> val z = add(2, 3)z: Int = 5
scala> val z = add(2, add(3, 4))z: Int = 9
scala>
def ����
Scala'*$)("��+scala��,
scala> def max(x: Int, y: Int) : Int = {| if (x > y) x| else y| }
max: (x: Int, y: Int)Intscala> val z = max(2, 3)z: Int = 3scala> def max(x: Int, y: Int) =
| if (x > y) x else ymax: (x: Int, y: Int)Intscala> val z = max(1, max(2, 3))z: Int = 3
IF-ELSE-������RETURN�����
������� ��!����
�����#&%�����
����
�����
��� ����
.$(��*/#-,"���2scala� 3
n Scala� ��!.$(��– .$(���::�)%10+'&�4.$(������!5
n .$(6 List() ��� Niln ��a, b, c�.$(6
– val list = List(a, b, c) ���
– a :: b :: c :: Nil ����!n ���: list.head => an � �.$(: list.tail => List(b,c)n �a".$(M�������.$(L
– L = a :: M
Scala��� "+$(��
n +$(��::�)%-,*'&�0+$(������"1
n ��.+$(��/ L = x::xs�0�����x�0!����+$(xs��" ��+$(#��1– x#L�����.=first(L)/���– xs#L�� ��.=rest(L)/���
n �/ x = a, xs = [b, c, d]���0x::xs = a::[b,c,d] = [a,b,c,d]
scala��n ��0+'/.,)(1
n NIl �-&*�,)(�$n X::L 2����-&*0�!#��1���-&*1�,)(�$3�"�2����X(�!#first(L))�� -&*M(�!#rest(L))%�#��$
//scala -&*�+'/.,)(zs match {
case Nil =>���%�$case x :: xs => ����x�� -&*xs����%�$
}
& !��#'�%$����(scala��)
n ��& !L������ sum(L)n �) L = List(1, 2, 3)���*sum(L) = 1 + 2 + 3
= 6
//scala & !����� def sum(L : List[Int]) : Int =
L match {case Nil => 0case x :: xs => x + sum(xs)
}// %�"�������sum(x) =
if is_nil(x) then 0 else first(x)+ sum(rest(x))
���
���� �������
scala> def sum(L : List[Int]) : Int =| L match {| case List() => 0| case x :: xs => x + sum(xs)| }
sum: (L: List[Int])Int
scala> val L = List(1, 2, 3)L: List[Int] = List(1, 2, 3)
scala> sum(L)res8: Int = 6
"����#�! ����$scala��%
n 2��"��X�Y��� append(X, Y)n �% X = List(1, 2), Y = List(3, 4, 5)���&
append(X, Y) = List(1, 2, 3, 4, 5)
//scala 2��"�����def append(x : List[Int], y : List[Int]) : List[Int] =
x match {case Nil => ycase z :: zs => z :: append(zs, y)
}
append(x, y) = //��!������� if is_nil(x) then y else cons((first(x), append(rest(x), y))
���
������������ ��scala��
n 2�����X�Y�� append(X, Y)
scala> def append(x : List[Int], y : List[Int]) : List[Int] =| x match {| case Nil => y| case z :: zs => z :: append(zs, y)| }
append: (x: List[Int], y: List[Int])List[Int]
scala> val z = append(List(1,2), List(3,4,5))z: List[Int] = List(1, 2, 3, 4, 5)scala>
����
A<=��>B;@?:�*$Dscala��En ��"H A<=X5�� reverser(X)
– �E reverse(List()) = List()– �E reverse(List(a, b, c, d)) = List(d, c, b, a)
n >B;@?5�%�– ��)+0F���1�%8– (i) �A<=5��6F�A<=G(ii) �!��' x 1F �A<='xs238A<=5��6Fxs:��+0�F��4x: �,97�#G
– A<=5 �46F�4/(.-append:�$C
B C D E FA
F E D C B A
x xs
x xsR
��"
4/0��15.32-���6scala��7
//scala4/0X(��(15.32//* 4/0X-*+"#8!(��X-� //* ��15.32append-���
def reverse(xs: List[Int]) : List[Int] = {xs match {case Nil => Nilcase y :: ys => append(reverse(ys), y::Nil)
}}
(i) 4/0(��)8 4/09(ii) ����� x $8��4/0�xs%&,4/0(��)8xs-���#��#8�'x-�� ,
���
���
arim@scala$ scalascala> :load append.scalaLoading append.scala...append: (xs: List[Int], y: List[Int])List[Int]reverse: (xs: List[Int])List[Int]
scala> reverse(List())res1: List[Int] = List()
scala> reverse(List(1,2,3))res2: List[Int] = List(3, 2, 1)
scala> reverse(List(1,2,3,4,5,6,7,8,9))res3: List[Int] = List(9, 8, 7, 6, 5, 4, 3, 2, 1)
��E>9:2��
n &2;?8=<reverser3C���n2>9:7��)521CO(n2)� 7�)5D
n &630*F
n ��E– O(n)�2�!��x7�,�5D– �!��x'/1Cappend.�(O(n)2��>9:xs2�1x7A��13�(12>9:x::NIl7B��)5D&63O(N)� 7�)5D
– 4+-C�-7��)521CO(n)"O(n) = O(n2)� $$5
n � @ O(n)� .��.%0#$F
����
���0��-()��*.',+
//reversefast.scala//2�"-()&O(n)� ���%
def reverse(xs: List[Int]) : List[Int] = reverse1(xs, Nil)
def reverse1(xs: List[Int], ys: List[Int]) : List[Int] = {xs match {case Nil => yscase z :: zs => reverse1(zs, z :: ys)
} //����ys!��-()&���%}
�� ��
2016.12.22: reverse/1"��"�$&��#��/
���
arim@scala$ scalascala> :load append.scalaLoading append.scala...append: (xs: List[Int], y: List[Int])List[Int]reverse: (xs: List[Int])List[Int]
scala> reverse(List())res1: List[Int] = List()
scala> reverse(List(1,2,3))res2: List[Int] = List(3, 2, 1)
scala> reverse(List(1,2,3,4,5,6,7,8,9))res3: List[Int] = List(9, 8, 7, 6, 5, 4, 3, 2, 1)
�����
DBC7�0@���"�)�
n %��5�7DBC7�/3<���"�7=@&!8���7)0@(',�$
n ���$�)�– )�f(x)8�,first(x), rest(x), f(rest(x))7=?� 8)�g(�#7fA:6+)4�;@.5,4-*f(nil)8�c,�:13+@)�
– ���)��#8���– �#8�E
f(x) = if is_nil(x) then c else g(first(x), rest(x), f(rest(x)))
– )�g8&!,�38DBC72+3��0@6>*f(x)8&!9��0@
����
�����
n 学ぶこと‒ 関数型プログラミング‒ 自然数に対する関数の帰納的定義‒ リスト処理‒ リストに対する関数の帰納的定義‒ Scala言語を使ってみよう
n プログラム‒ 自然数: • 足し算plus, 掛け算times
‒ リスト処理• リストの要素の総和• 二つのリストの連結• リストの反転:ふつう版と高速版