ERLANG (cont.) Funktionale Programmierung Materialien zur Vorlesung D. Rösner Institut für Wissens- und Sprachverarbeitung Fakultät für Informatik Otto-von-Guericke Universität Magdeburg c Sommer 2011, 7. April 2011, 2011 D.Rösner D. Rösner FP 2011 . . . 1 ERLANG (cont.) Gliederung 1 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen D. Rösner FP 2011 . . . 2 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Pattern matching in ERLANG Pattern matching in ERLANG ist von Prolog inspiriert im Unterschied zu Haskell dürfen auch im Pattern Variable mehrfach vorkommen daher muss in solchen Fällen die Gleichheit der Werte nicht durch zusätzliche ‘guards’ geprüft werden D. Rösner FP 2011 . . . 4 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Pattern matching in Haskell allEqual :: Eq a => [a] -> Bool allEqual [] = True allEqual [_] = True allEqual (el1:el2:rest) = if el1 == el2 then allEqual (el2:rest) else False D. Rösner FP 2011 . . . 5 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Pattern matching in Erlang -module(allequal). -export([allequal/1]). allequal([]) -> true; allequal([_]) -> true; allequal([X,X|T]) -> allequal([X|T]); allequal([_,_|_]) -> false. D. Rösner FP 2011 . . . 6 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Pattern matching in Erlang -module(interval). -export([interval/2]). %interval(Low,High) when Low == High -> [High]; %% this guard can be captured in the pattern interval(High,High) -> [High]; interval(Low,High) when Low < High -> [Low] ++ interval(Low+1,High); interval(_,_) -> []. D. Rösner FP 2011 . . . 7 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Vergleich zwischen Erlang, Prolog und Haskell Aneinanderfügen zweier Listen als Relation in Prolog bzw. als Funktion in Erlang bzw. Haskell als Beispiel Bemerkungen: in allen Sprachen vordefiniert Haskell: ++ . . . Infix-Operator Erlang: ++ . . . Infix-Operator Prolog: append/3 D. Rösner FP 2011 . . . 9 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Funktion append in Haskell append :: [a] -> [a] -> [a] append [] ys = ys append (x:xs) ys = x:(append xs ys) Bemerkungen: strenge Typisierung Polymorphie D. Rösner FP 2011 . . . 10 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Funktion append in Erlang -module(append). -export([append/2]). append([],Y) -> Y; append([X|T],Y) -> [X|append(T,Y)]. D. Rösner FP 2011 . . . 11 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Relation append in Prolog append([],Y,Y). append([X|T],Y,[X|R]) :- append(T,Y,R). Bemerkungen: in unterschiedlicher Weise verwendbar D. Rösner FP 2011 . . . 12 ERLANG (cont.) 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: 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 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Unendliche Listen in Scheme werden gewöhnliche Listen – und andere Datenstrukturen – strikt (oder ’eager’) ausgewertet mit cons-stream können sog. Ströme gebildet werden D. Rösner FP 2011 . . . 15 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Ströme: Sprachmittel in SCHEME Konstruktor: cons-stream 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. Konstante: the-empty-stream Prädikat: empty-stream? D. Rösner FP 2011 . . . 16 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Ströme: Implementation Implementation von Strömen durch verzögerte Evaluation (delayed evaluation, lazy evaluation) in normalen Listen: car und cdr werden zur Konstruktionszeit evaluiert 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 (force <promise>) . . . veranlasst Ausführung von <promise> D. Rösner FP 2011 . . . 17 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Implementation cont. (cons-stream <a><b>) . . . Spezialform, die gleichwertig mit (cons <a> (delay <b>)) d.h. Strom wird als Paar dargestellt im cdr steht promise zur Berechnung des tail (define (head stream) (car stream)) (define (tail stream) (force (cdr stream))) D. Rösner FP 2011 . . . 18 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Unendlich lange Ströme Strom positiver ganzer Zahlen (define (integers-starting-from n) (cons-stream n (integers-starting-from (1+ n)))) (define integers (integers-starting-from 1)) Strom von Fibonacci-Zahlen (define (fibgen a b) (cons-stream a (fibgen b (+ a b)))) (define fibs (fibgen 0 1)) D. Rösner FP 2011 . . . 19 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Unendlich lange Ströme cont. 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))) D. Rösner FP 2011 . . . 20 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Unendliche Listen in Erlang mit ‘lazy embedding’ lassen sich in Erlang unendliche Listen kreieren -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 . . . 21 ERLANG (cont.) 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 . . . 22 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Unendliche Listen in Erlang 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" D. Rösner FP 2011 . . . 23 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen 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 . . . 24 ERLANG (cont.) Pattern matching Vergleich Unendliche Listen Unendliche Listen in Erlang 11> (tl(CC()))(). [100|#Fun<lazy.1.109043180>] Variante: 11> apply(tl(CC()),[]). [100|#Fun<lazy.1.109043180>] D. Rösner FP 2011 . . . 25 ERLANG (cont.) 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