Funktionales Programmieren
mit Beispielen in Haskell und Java,
License: CC-BY-SA-4.0
Martin Heuschober
2017-06-28
|
|
Eine Programmiersprache darf sich (meiner Meinung nach) funktional nennen wenn:
jede Funktion einen Rückgabewert hat.
Bonuspunkte gibt es für partielle Funktionsaufrufe, i.e. wenn eine Funktion mit mehreren Parametern mit nur einem Parameter aufrufbar ist, und eine Funktion mit um einen Parameter weniger zurückgibt.
Java8 |
Aufgabe: (Stackoverflow) Mache aus einer Liste: [5,4,2]
=> "+-----+----+--+"
Mache aus einer Liste: [5,4,2]
=> "| + + |"
map
for
-loop††: Ich glaube aber fast das gleiche wie eine foreach
-loop
fold
/reduce
filter
all
/any
Aus der Dokumentation von node.js (fast wortgetreu) fs.openSync(path, flags[, mode])
path <string> | <Buffer> | <URL>
flags <string> | <number>
mode <integer>
Synchronous version of fs.open(). Returns an integer representing the file descriptor.
<integer>
oder auch Kommazahlen?machen ja auch alle - und kopieren nicht einfach Code von Stackoverflow
Jeder Fehler der zur Compile-time erkannt wird, landet nie bei einem Kunden.
case runParser ipv4 "127.-1.120.255"
of Left msg -> do something with errormessage
Right x -> do something with result
ipv4 :: Parser IPv4
ipv4 = do a <- check =<< decimal
dot
b <- check =<< decimal
dot
c <- check =<< decimal
dot
d <- check =<< decimal
return IPv4 a b c d
where dot :: Parser ()
dot = void $ char '.'
check :: Integral -> Parser Word8
check x = do unless (0 <= x && x <= 256) $
fail "Failed parsing IPv4"
return $ fromIntegral x
[]
und (:)
sind Listenkonstruktoren (leere Liste und cons
-Operator) => 2tes Argument von map
muss eine Liste sein.
ebenso das Ergebnis
f
wird in Zeile 2 auf das erste Element der Argument-Liste angewandt => damit muss f
eine Funktion sein
f
wird in Zeile 2 auf das erste Element der Argument-Liste angewandt => damit muss f
der Wertebereich von f
a
sein und der Zielbereich b
NonNullable
/@Nullable
verwendenList.append(x)
verändert eine Liste und ist daher eine schlechte Idee . . .“We can solve any problem by introducing an extra level of indirection.”
Butler Lampson
Ziel: Einen Container-Datentyp elementweise verändern, aber die Struktur des Containers beibehalten. Warum: Fast jeder Container hat diese Eigenschaft.
import java.util.function.Function;
interface Functor<T> {
<R> Functor<R> fmap(Function<T, R> f);
}
interface Functor<T,F extends Functor<?,?>> {
<R> F fmap(Function<T,R> f);
}
class Identity<T> implements Functor<T,Identity<?>> {
private final T value;
Identity(T value) { this.value = value; }
public <R> Identity<R> fmap(Function<T,R> f) {
final R result = f.apply(value);
return new Identity<>(result);
}
}