ERLANG (cont.) ERLANG (cont.) Gliederung Funktionale Programmierung Materialien zur Vorlesung 1 D. Rösner Institut für Wissens- und Sprachverarbeitung Fakultät für Informatik Otto-von-Guericke Universität Magdeburg ERLANG (cont.) Pattern matching Vergleich Unendliche Listen c Sommer 2011, 7. April 2011, 2011 D.Rösner D. Rösner FP 2011 . . . ERLANG (cont.) D. Rösner FP 2011 . . . 1 Pattern matching Vergleich Unendliche Listen ERLANG (cont.) 2 Pattern matching Vergleich Unendliche Listen Pattern matching in Haskell Pattern matching in ERLANG allEqual :: Eq a => [a] -> Bool Pattern matching in ERLANG ist von Prolog inspiriert allEqual [] = True im Unterschied zu Haskell dürfen auch im Pattern Variable mehrfach vorkommen allEqual [_] = True daher muss in solchen Fällen die Gleichheit der Werte nicht durch zusätzliche ‘guards’ geprüft werden D. Rösner FP 2011 . . . allEqual (el1:el2:rest) = if el1 == el2 then allEqual (el2:rest) else False 4 D. Rösner FP 2011 . . . 5 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen ERLANG (cont.) Pattern matching in Erlang Pattern matching in Erlang -module(interval). -export([interval/2]). -module(allequal). -export([allequal/1]). %interval(Low,High) when Low == High -> [High]; %% this guard can be captured in the pattern allequal([]) -> true; allequal([_]) -> true; allequal([X,X|T]) -> allequal([X|T]); allequal([_,_|_]) -> false. D. Rösner FP 2011 . . . ERLANG (cont.) Pattern matching Vergleich Unendliche Listen interval(High,High) -> [High]; interval(Low,High) when Low < High -> [Low] ++ interval(Low+1,High); interval(_,_) -> []. 6 D. Rösner FP 2011 . . . Pattern matching Vergleich Unendliche Listen ERLANG (cont.) Vergleich zwischen Erlang, Prolog und Haskell 7 Pattern matching Vergleich Unendliche Listen Funktion append in Haskell Aneinanderfügen zweier Listen als Relation in Prolog bzw. als Funktion in Erlang bzw. Haskell als Beispiel Bemerkungen: append :: [a] -> [a] -> [a] append [] ys = ys in allen Sprachen vordefiniert append (x:xs) ys = x:(append xs ys) Haskell: ++ . . . Infix-Operator Erlang: ++ . . . Infix-Operator Prolog: append/3 Bemerkungen: strenge Typisierung Polymorphie D. Rösner FP 2011 . . . 9 D. Rösner FP 2011 . . . 10 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen ERLANG (cont.) Funktion append in Erlang Pattern matching Vergleich Unendliche Listen Relation append in Prolog -module(append). -export([append/2]). append([],Y,Y). append([X|T],Y,[X|R]) :- append(T,Y,R). append([],Y) -> Y; append([X|T],Y) -> [X|append(T,Y)]. Bemerkungen: in unterschiedlicher Weise verwendbar D. Rösner FP 2011 . . . ERLANG (cont.) 11 D. Rösner FP 2011 . . . Pattern matching Vergleich Unendliche Listen ERLANG (cont.) Unendliche Listen 12 Pattern matching Vergleich Unendliche Listen Unendliche Listen da in Haskell grundsätzlich ‘lazy’ evaluiert wird, werden für unendliche Listen in Haskell keine zusätzlichen Sprachmittel benötigt Beispiel: in Scheme werden gewöhnliche Listen – und andere Datenstrukturen – strikt (oder ’eager’) ausgewertet mit cons-stream können sog. Ströme gebildet werden fibgen a b = a:(fibgen b (a + b)) fibs = fibgen 0 1 Main> take 10 fibs [0,1,1,2,3,5,8,13,21,34] D. Rösner FP 2011 . . . 14 D. Rösner FP 2011 . . . 15 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen ERLANG (cont.) Ströme: Sprachmittel in SCHEME Pattern matching Vergleich Unendliche Listen Ströme: Implementation Implementation von Strömen durch verzögerte Evaluation (delayed evaluation, lazy evaluation) Konstruktor: cons-stream in normalen Listen: car und cdr werden zur Konstruktionszeit evaluiert Selektoren: head, tail Beziehung: für bel. a,b und x: Wenn x ist (cons-stream a b), dann (head x) ist a und (tail x) ist b. in Strömen: tail erst zur Zugriffszeit evaluieren (call-by-need) Spezialform delay: (delay <exp>) . . . liefert ein verzögertes Objekt, sog. promise, dass erst mit force zur Ausführung veranlasst wird Konstante: the-empty-stream Prädikat: empty-stream? (force <promise>) . . . veranlasst Ausführung von <promise> D. Rösner FP 2011 . . . ERLANG (cont.) 16 Pattern matching Vergleich Unendliche Listen D. Rösner FP 2011 . . . ERLANG (cont.) Implementation cont. 17 Pattern matching Vergleich Unendliche Listen Unendlich lange Ströme Strom positiver ganzer Zahlen (cons-stream <a><b>) . . . Spezialform, die gleichwertig mit (cons <a> (delay <b>)) (define (integers-starting-from n) (cons-stream n (integers-starting-from (1+ n)))) (define integers (integers-starting-from 1)) d.h. Strom wird als Paar dargestellt im cdr steht promise zur Berechnung des tail Strom von Fibonacci-Zahlen (define (head stream) (car stream)) (define (fibgen a b) (cons-stream a (fibgen b (+ a b)))) (define (tail stream) (force (cdr stream))) (define fibs (fibgen 0 1)) D. Rösner FP 2011 . . . 18 D. Rösner FP 2011 . . . 19 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen ERLANG (cont.) Unendlich lange Ströme cont. Pattern matching Vergleich Unendliche Listen Unendliche Listen in Erlang mit ‘lazy embedding’ lassen sich in Erlang unendliche Listen kreieren Sieb des Eratosthenes (define (sieve stream) (cons-stream (head stream) (sieve (filter (lambda (x) (not (divisible? x (head stream)))) (tail stream))))) (define primes (sieve (integers-starting-from 2))) -module(lazy). -export([ints_from/1,take/2, add/2]). ints_from(N) -> fun() -> [N|ints_from(N+1)] end. ... D. Rösner FP 2011 . . . ERLANG (cont.) 20 Pattern matching Vergleich Unendliche Listen ERLANG (cont.) Unendliche Listen in Erlang 21 Pattern matching Vergleich Unendliche Listen Unendliche Listen in Erlang ... take(N,Lazy) -> if N == 0 -> []; true -> [hd(Lazy()) | take(N-1,tl(Lazy()))] end. %% analog zu add-stream in Scheme add([], _) -> []; add(_,[]) -> []; add(Lazy1, Lazy2) -> fun() -> [hd(Lazy1()) + hd(Lazy2()) | add(tl(Lazy1()), tl(Lazy2()))] end. D. Rösner FP 2011 . . . D. Rösner FP 2011 . . . 1> c("C:/Daten/roesner/erlang/modules/lazy.erl"). {ok,lazy} 2> CC = lazy:add(lazy:ints_from(97),lazy:ints_from(1)). #Fun<lazy.1.109043180> 6> lazy:take(2,CC). "bd" 22 D. Rösner FP 2011 . . . 23 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen ERLANG (cont.) Unendliche Listen in Erlang Unendliche Listen in Erlang 8> CC. #Fun<lazy.1.109043180> 9> CC(). [98|#Fun<lazy.1.109043180>] 10> tl(CC()). #Fun<lazy.1.109043180> D. Rösner FP 2011 . . . ERLANG (cont.) Pattern matching Vergleich Unendliche Listen 11> (tl(CC()))(). [100|#Fun<lazy.1.109043180>] Variante: 11> apply(tl(CC()),[]). [100|#Fun<lazy.1.109043180>] 24 Pattern matching Vergleich Unendliche Listen Literatur: I Joe Armstrong. Programming Erlang – Software for a Concurrent World. The Pragmatic Bookshelf, Raleigh, North Carolina; Dallas, Texas, 2007. ISBN 1-9343560-0. Joe Armstrong, Robert Virding, Claes Wikström, and Mike Williams. Concurrent Programming in ERLANG – Second Edition. Pearson Education Ltd., Harlow, Essex GB, 1996. ISBN 0-13-508301-X; A preprint of Part I is available for download from http://www.erlang.org/download/erlang-book-part1.pdf. D. Rösner FP 2011 . . . 26 D. Rösner FP 2011 . . . 25