mirror of
https://github.com/MartinThoma/LaTeX-examples.git
synced 2025-04-26 06:48:04 +02:00
Viel zu Haskell ergänzt; Funktionen höherer Ordnung beschrieben
This commit is contained in:
parent
aa2454bb30
commit
78368fa6e9
17 changed files with 220 additions and 24 deletions
|
@ -8,3 +8,4 @@ in dem Erstellen dieses Skripts steckt:
|
||||||
|01.02.2014 | 14:45 - 15:30 | Thoma | Haskell angefangen
|
|01.02.2014 | 14:45 - 15:30 | Thoma | Haskell angefangen
|
||||||
|01.02.2014 | 11:15 - 11:45 | Thoma | Haskell Class Hierachy
|
|01.02.2014 | 11:15 - 11:45 | Thoma | Haskell Class Hierachy
|
||||||
|01.02.2014 | 16:00 - 17:00 | Thoma | Abschnitt über Rekursion hinzugefügt
|
|01.02.2014 | 16:00 - 17:00 | Thoma | Abschnitt über Rekursion hinzugefügt
|
||||||
|
|04.02.2014 | 13:00 - 14:00 | Thoma | Viel zu Haskell ergänzt; Funktionen höherer Ordnung beschrieben
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
\chapter{Haskell}
|
\chapter{Haskell}
|
||||||
\index{Haskell|(}
|
\index{Haskell|(}
|
||||||
Haskell ist eine funktionale Programmiersprache, die von Haskell
|
Haskell ist eine funktionale Programmiersprache, die von Haskell
|
||||||
Brooks Curry entwickelt wurde und 1990 in Version~1.0 veröffentlicht
|
Brooks Curry entwickelt und 1990 in Version~1.0 veröffentlicht
|
||||||
wurde.
|
wurde.
|
||||||
|
|
||||||
Wichtige Konzepte sind:
|
Wichtige Konzepte sind:
|
||||||
|
@ -21,24 +21,44 @@ Haskell kann unter \href{http://www.haskell.org/platform/}{\path{www.haskell.org
|
||||||
für alle Plattformen heruntergeladen werden. Unter Debian-Systemen
|
für alle Plattformen heruntergeladen werden. Unter Debian-Systemen
|
||||||
ist das Paket \texttt{ghc} bzw. \texttt{haskell-platform} relevant.
|
ist das Paket \texttt{ghc} bzw. \texttt{haskell-platform} relevant.
|
||||||
|
|
||||||
\section{Typen}
|
\subsection{Hello World}
|
||||||
Siehe \cref{fig:haskell-type-hierarchy}:
|
Speichere folgenden Quelltext als \texttt{hello-world.hs}:
|
||||||
|
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=hello-world.hs]{haskell}{scripts/haskell/hello-world.hs}
|
||||||
|
|
||||||
\begin{figure}[htp]
|
Kompiliere ihn mit \texttt{ghc -o hello hello-world.hs}. Es wird eine
|
||||||
\centering
|
ausführbare Datei erzeugt.
|
||||||
\resizebox{0.9\linewidth}{!}{\input{figures/haskell-type-classes.tex}}
|
|
||||||
\caption{Hierarchie der Haskell Standardklassen}
|
|
||||||
\label{fig:haskell-type-hierarchy}
|
|
||||||
\end{figure}
|
|
||||||
|
|
||||||
\section{Syntax}
|
\section{Syntax}
|
||||||
\subsection{Klammern}
|
\subsection{Klammern und Funktionsdeklaration}
|
||||||
Haskell verzichtet an vielen Stellen auf Klammern. So werden im
|
Haskell verzichtet an vielen Stellen auf Klammern. So werden im
|
||||||
Folgenden die Funktionen $f(x) := \frac{\sin x}{x}$ und $g(x) := x \cdot f(x^2)$
|
Folgenden die Funktionen $f(x) := \frac{\sin x}{x}$ und $g(x) := x \cdot f(x^2)$
|
||||||
definiert:
|
definiert:
|
||||||
|
|
||||||
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/einfaches-beispiel-klammern.hs}
|
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/einfaches-beispiel-klammern.hs}
|
||||||
|
|
||||||
|
Die Funktionsdeklarationen mit den Typen sind nicht notwendig, da
|
||||||
|
die Typen aus den benutzten Funktionen abgeleitet werden.
|
||||||
|
|
||||||
|
Zu lesen ist die Deklaration wie folgt:
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\texttt{[Funktionsname] :: \texttt{[Typendefinitionen]} => \texttt{Signatur}}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item[T. Def.] Die Funktion \texttt{f} benutzt als Parameter bzw. Rückgabewert
|
||||||
|
einen Typen. Diesen Typen nennen wir \texttt{a} und er ist
|
||||||
|
vom Typ \texttt{Floating}. Auch \texttt{b}, \texttt{wasweisich}
|
||||||
|
oder etwas ähnliches wäre ok.
|
||||||
|
\item[Signatur] Die Signatur liest man am einfachsten von hinten:
|
||||||
|
\begin{itemize}
|
||||||
|
\item \texttt{f} bildet auf einen Wert vom Typ \texttt{a} ab und
|
||||||
|
\item \texttt{f} hat genau einen Parameter \texttt{a}
|
||||||
|
\end{itemize}
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\todo[inline]{Gibt es Funktionsdeklarationen, die äquivalent? (bis auf wechsel des namens und der Reihenfolge)}
|
||||||
|
|
||||||
\subsection{if / else}
|
\subsection{if / else}
|
||||||
Das folgende Beispiel definiert den Binomialkoeffizienten (vgl. \cref{bsp:binomialkoeffizient})
|
Das folgende Beispiel definiert den Binomialkoeffizienten (vgl. \cref{bsp:binomialkoeffizient})
|
||||||
|
|
||||||
|
@ -61,23 +81,86 @@ hat einen Speicherverbrauch von $\mathcal{O}(n)$. Durch einen
|
||||||
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/fakultaet-akkumulator.hs}
|
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/fakultaet-akkumulator.hs}
|
||||||
|
|
||||||
\subsection{Listen}
|
\subsection{Listen}
|
||||||
\todo[inline]{Cons-Operator, Unendliche Listen}
|
\begin{itemize}
|
||||||
|
\item \texttt{[]} erzeugt die leere Liste,
|
||||||
|
\item \texttt{[1,2,3]} erzeugt eine Liste mit den Elementen $1, 2, 3$
|
||||||
|
\item \texttt{:} wird \textbf{cons}\xindex{cons} genannt und ist
|
||||||
|
der Listenkonstruktor.
|
||||||
|
\item \texttt{head list} gibt den Kopf von \texttt{list} zurück,
|
||||||
|
\texttt{tail list} den Rest:
|
||||||
|
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/list-basic.sh}
|
||||||
|
\item \texttt{null list} prüft, ob \texttt{list} leer ist.
|
||||||
|
\item \texttt{length list} gibt die Anzahl der Elemente in \texttt{list} zurück.
|
||||||
|
\item \texttt{maximum [1,9,1,3]} gibt 9 zurück (analog: \texttt{minimum}).
|
||||||
|
\item \texttt{last [1,9,1,3]} gibt 3 zurück.
|
||||||
|
\item \texttt{reverse [1,9,1,3]} gibt \texttt{[3,1,9,1]} zurück.
|
||||||
|
\item \texttt{elem item list} gibt zurück, ob sich \texttt{item} in \texttt{list} befindet.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
\subsubsection{Beispiel in der interaktiven Konsole}
|
\subsubsection{Beispiel in der interaktiven Konsole}
|
||||||
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/listenoperationen.sh}
|
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/listenoperationen.sh}
|
||||||
|
|
||||||
|
\subsubsection{List-Comprehensions}\xindex{List-Comprehension}
|
||||||
|
List-Comprehensions sind kurzschreibweisen für Listen, die sich an
|
||||||
|
der Mengenschreibweise in der Mathematik orientieren. So entspricht
|
||||||
|
die Menge
|
||||||
|
\begin{align*}
|
||||||
|
myList &= \Set{1,2,3,4,5,6}\\
|
||||||
|
test &= \Set{x \in myList | x > 2}
|
||||||
|
\end{align*}
|
||||||
|
in etwa folgendem Haskell-Code:
|
||||||
|
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/list-comprehensions.sh}
|
||||||
|
|
||||||
|
\subsection{Strings}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Strings sind Listen von Zeichen:\\
|
||||||
|
\texttt{tail "ABCDEF"} gibt \texttt{"BCDEF"} zurück.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\section{Typen}
|
||||||
|
In Haskell werden Typen aus den Operationen geschlossfolgert. Dieses
|
||||||
|
Schlussfolgern der Typen, die nicht explizit angegeben werden müssen,
|
||||||
|
nennt man \textbf{Typinferent}\xindex{Typinferenz}.
|
||||||
|
|
||||||
|
|
||||||
|
Haskell kennt die Typen aus \cref{fig:haskell-type-hierarchy}.
|
||||||
|
|
||||||
|
Ein paar Beispiele zur Typinferenz:
|
||||||
|
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/typinferenz.sh}
|
||||||
|
|
||||||
|
\begin{figure}[htp]
|
||||||
|
\centering
|
||||||
|
\resizebox{0.9\linewidth}{!}{\input{figures/haskell-type-classes.tex}}
|
||||||
|
\caption{Hierarchie der Haskell Standardklassen}
|
||||||
|
\label{fig:haskell-type-hierarchy}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
\section{Beispiele}
|
\section{Beispiele}
|
||||||
\subsection{Hello World}
|
\subsection{Quicksort}
|
||||||
Speichere folgenden Quelltext als \texttt{hello-world.hs}:
|
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=qsort.hs]{haskell}{scripts/haskell/qsort.hs}
|
||||||
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=hello-world.hs]{haskell}{scripts/haskell/hello-world.hs}
|
|
||||||
|
|
||||||
Kompiliere ihn mit \texttt{ghc -o hello hello-world.hs}. Es wird eine
|
\begin{itemize}
|
||||||
ausführbare Datei erzeugt.
|
\item Die leere Liste ergibt sortiert die leere Liste.
|
||||||
|
\item Wähle das erste Element \texttt{p} als Pivotelement und
|
||||||
|
teile die restliche Liste \texttt{ps} in kleinere und
|
||||||
|
gleiche sowie in größere Elemente mit \texttt{filter} auf.
|
||||||
|
Konkateniere diese beiden Listen mit \texttt{++}.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
\subsection{Fibonacci}
|
Durch das Ausnutzen von Unterversorgung\xindex{Unterversorgung} lässt
|
||||||
|
sich das ganze sogar noch kürzer schreiben:
|
||||||
|
|
||||||
|
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=qsort.hs]{haskell}{scripts/haskell/qsort-unterversorg.hs}
|
||||||
|
|
||||||
|
\subsection{Fibonacci}\xindex{Fibonacci}
|
||||||
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci.hs]{haskell}{scripts/haskell/fibonacci.hs}
|
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci.hs]{haskell}{scripts/haskell/fibonacci.hs}
|
||||||
|
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-akk.hs]{haskell}{scripts/haskell/fibonacci-akk.hs}
|
||||||
|
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-zip.hs]{haskell}{scripts/haskell/fibonacci-zip.hs}
|
||||||
|
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-pattern-matching.hs]{haskell}{scripts/haskell/fibonacci-pattern-matching.hs}
|
||||||
|
|
||||||
\subsection{Quicksort}
|
\subsection{Quicksort}
|
||||||
|
\subsection{Funktionen höherer Ordnung}
|
||||||
|
|
||||||
|
|
||||||
\section{Weitere Informationen}
|
\section{Weitere Informationen}
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
|
|
Binary file not shown.
|
@ -18,9 +18,10 @@
|
||||||
fib(n-1) + fib(n-2) &\text{sonst}
|
fib(n-1) + fib(n-2) &\text{sonst}
|
||||||
\end{cases}
|
\end{cases}
|
||||||
\end{align*}
|
\end{align*}
|
||||||
|
Erzeugt die Zahlen $0, 1, 1, 2, 3, 5, 8, 13, \dots$
|
||||||
\item Fakultät:\xindex{Fakultät}
|
\item Fakultät:\xindex{Fakultät}
|
||||||
\begin{align*}
|
\begin{align*}
|
||||||
!: \mdn_0 &\rightarrow \mdn_0\\
|
! &: \mdn_0 \rightarrow \mdn_0\\
|
||||||
n! &= \begin{cases}
|
n! &= \begin{cases}
|
||||||
1 &\text{falls } n \leq 1\\
|
1 &\text{falls } n \leq 1\\
|
||||||
n\cdot (n-1)! &\text{sonst}
|
n\cdot (n-1)! &\text{sonst}
|
||||||
|
@ -28,7 +29,7 @@
|
||||||
\end{align*}
|
\end{align*}
|
||||||
\item \label{bsp:binomialkoeffizient} Binomialkoeffizient:\xindex{Binomialkoeffizient}
|
\item \label{bsp:binomialkoeffizient} Binomialkoeffizient:\xindex{Binomialkoeffizient}
|
||||||
\begin{align*}
|
\begin{align*}
|
||||||
\binom{\cdot}{\cdot}: \mdn_0 \times \mdn_0 &\rightarrow \mdn_0\\
|
\binom{\cdot}{\cdot} &: \mdn_0 \times \mdn_0 \rightarrow \mdn_0\\
|
||||||
\binom{n}{k} &= \begin{cases}
|
\binom{n}{k} &= \begin{cases}
|
||||||
1 &\text{falls } k=0 \lor k = n\\
|
1 &\text{falls } k=0 \lor k = n\\
|
||||||
\binom{n-1}{k-1}+\binom{n-1}{k} &\text{sonst}
|
\binom{n-1}{k-1}+\binom{n-1}{k} &\text{sonst}
|
||||||
|
@ -79,20 +80,54 @@ Mit Hilfe der Formel von Moivre-Binet folgt:
|
||||||
Dabei ist der Speicherbedarf $\mathcal{O}(n)$. Dieser kann durch
|
Dabei ist der Speicherbedarf $\mathcal{O}(n)$. Dieser kann durch
|
||||||
das Benutzen eines Akkumulators signifikant reduziert werden.\todo{TODO}
|
das Benutzen eines Akkumulators signifikant reduziert werden.\todo{TODO}
|
||||||
|
|
||||||
\begin{definition}[linear rekursive Funktion]\xindex{Funktion!linear rekursive}
|
\begin{definition}[linear rekursive Funktion]\xindex{Funktion!linear rekursive}%
|
||||||
Eine Funktion heißt linear rekursiv, wenn in jedem Definitionszweig
|
Eine Funktion heißt linear rekursiv, wenn in jedem Definitionszweig
|
||||||
der Funktion höchstens ein rekursiver Aufruf vorkommt.
|
der Funktion höchstens ein rekursiver Aufruf vorkommt.
|
||||||
\end{definition}
|
\end{definition}
|
||||||
|
|
||||||
\begin{definition}[endrekursive Funktion]\xindex{Funktion!endrekursive}\xindex{tail recursive}
|
\begin{definition}[endrekursive Funktion]\xindex{Funktion!endrekursive}\xindex{tail recursive}%
|
||||||
Eine Funktion heißt endrekursiv, wenn in jedem Definitionszweig
|
Eine Funktion heißt endrekursiv, wenn in jedem Definitionszweig
|
||||||
der Rekursive aufruf am Ende des Ausdrucks steht. Der rekursive
|
der Rekursive aufruf am Ende des Ausdrucks steht. Der rekursive
|
||||||
Aufruf darf also insbesondere nicht in einen anderen Ausdruck
|
Aufruf darf also insbesondere nicht in einen anderen Ausdruck
|
||||||
eingebettet sein.
|
eingebettet sein.
|
||||||
\end{definition}
|
\end{definition}
|
||||||
|
|
||||||
\todo[inline]{Beispiele für linear rekusrive, endrekursive Funktionen (alle Kombinationen+gegenbeispiele}
|
Auf Englisch heißen endrekursive Funktionen \textit{tail recursive}.
|
||||||
|
|
||||||
\index{Rekursion|(}
|
\begin{beispiel}[Linear- und endrekursive Funktionen]
|
||||||
|
\begin{bspenum}
|
||||||
|
\item \texttt{fak n = if (n==0) then 1 else (n * fak (n-1))}\\
|
||||||
|
ist eine linear rekursive Funkion, aber nicht endrekursiv,
|
||||||
|
da nach der Rückgabe von \texttt{fak (n-1)} noch die Multiplikation
|
||||||
|
ausgewertet werden muss.
|
||||||
|
\item \texttt{fakAcc n acc = if (n==0) then acc else fakAcc (n-1) (n*acc)}\\
|
||||||
|
ist eine endrekursive Funktion.
|
||||||
|
\item \texttt{fib n = n <= 1 ? n : fib(n-1) + fib (n-2)}\\
|
||||||
|
ist weder linear- noch endrekursiv.
|
||||||
|
\end{bspenum}
|
||||||
|
\end{beispiel}
|
||||||
|
|
||||||
|
\index{Rekursion|)}
|
||||||
\section{Backtracking}
|
\section{Backtracking}
|
||||||
|
\index{Backtracking|(}
|
||||||
|
|
||||||
|
\index{Backtracking|)}
|
||||||
|
|
||||||
|
\section{Funktionen höherer Ordnung}
|
||||||
|
Funktionen höherer Ordnung sind Funktionen, die auf Funktionen arbeiten.
|
||||||
|
Bekannte Beispiele sind:
|
||||||
|
\begin{itemize}
|
||||||
|
\item \texttt{map(function, list)}\xindex{map}\\
|
||||||
|
\texttt{map} wendet \texttt{function} auf jedes einzelne
|
||||||
|
Element aus \texttt{list} an.
|
||||||
|
\item \texttt{filter(function, list)}\xindex{filter}\\
|
||||||
|
\texttt{filter} gibt eine Liste aus Elementen zurück, für
|
||||||
|
die \texttt{function} mit \texttt{true} evaluiert.
|
||||||
|
\item \texttt{reduce(function, list)}\xindex{reduce}\\
|
||||||
|
\texttt{function} ist für zwei Elemente aus \texttt{list}
|
||||||
|
definiert und gibt ein Element des gleichen Typs zurück.
|
||||||
|
Nun steckt \texttt{reduce} zuerst zwei Elemente aus \texttt{list}
|
||||||
|
in \texttt{function}, merkt sich dann das Ergebnis und nimmt
|
||||||
|
so lange weitere Elemente aus \texttt{list}, bis jedes
|
||||||
|
Element genommen wurde.
|
||||||
|
\end{itemize}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
binom :: (Eq a, Num a, Num a1) => a -> a -> a1
|
||||||
binom n k =
|
binom n k =
|
||||||
if (k==0) || (k==n)
|
if (k==0) || (k==n)
|
||||||
then 1
|
then 1
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
|
f :: Floating a => a -> a
|
||||||
f x = sin x / x
|
f x = sin x / x
|
||||||
|
|
||||||
|
g :: Floating a => a -> a
|
||||||
g x = x * (f (x*x))
|
g x = x * (f (x*x))
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
fakAcc :: (Eq a, Num a) => a -> a -> a
|
||||||
fakAcc n acc = if (n==0)
|
fakAcc n acc = if (n==0)
|
||||||
then acc
|
then acc
|
||||||
else fakAcc (n-1) (n*acc)
|
else fakAcc (n-1) (n*acc)
|
||||||
|
|
||||||
|
fak :: (Eq a, Num a) => a -> a
|
||||||
fak n = fakAcc n 1
|
fak n = fakAcc n 1
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
|
fak :: (Eq a, Num a) => a -> a
|
||||||
fak n = if (n==0) then 1 else n * fak (n-1)
|
fak n = if (n==0) then 1 else n * fak (n-1)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
fibAkk n n1 n2
|
||||||
|
| (n == 0) = n1
|
||||||
|
| (n == 1) = n2
|
||||||
|
| otherwise = fibAkk (n - 1) n2 (n1 + n2)
|
||||||
|
fib n = fibAkk n 0 1
|
|
@ -0,0 +1,3 @@
|
||||||
|
fib 0 = 0
|
||||||
|
fib 1 = 1
|
||||||
|
fib n = fib (n - 1) + fib (n - 2)
|
|
@ -0,0 +1 @@
|
||||||
|
fib = 0 : 1 : zipWith (+) fibs (tail fibs)
|
|
@ -1 +1,4 @@
|
||||||
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
|
fib n
|
||||||
|
| (n == 0) = 0
|
||||||
|
| (n == 1) = 1
|
||||||
|
| otherwise = fib (n - 1) + fib (n - 2)
|
|
@ -0,0 +1,12 @@
|
||||||
|
Prelude> head []
|
||||||
|
*** Exception: Prelude.head: empty list
|
||||||
|
Prelude> tail []
|
||||||
|
*** Exception: Prelude.tail: empty list
|
||||||
|
Prelude> tail [1]
|
||||||
|
[]
|
||||||
|
Prelude> head [1]
|
||||||
|
1
|
||||||
|
Prelude> null []
|
||||||
|
True
|
||||||
|
Prelude> null [[]]
|
||||||
|
False
|
|
@ -0,0 +1,4 @@
|
||||||
|
Prelude> let mylist = [1,2,3,4,5,6]
|
||||||
|
Prelude> let test = [x | x <- mylist, x>2]
|
||||||
|
Prelude> test
|
||||||
|
[3,4,5,6]
|
|
@ -0,0 +1,3 @@
|
||||||
|
qsort [] = []
|
||||||
|
qsort (p:ps) = (qsort (filter (<=p) ps))
|
||||||
|
++ p:(qsort (filter (> p) ps))
|
3
documents/Programmierparadigmen/scripts/haskell/qsort.hs
Normal file
3
documents/Programmierparadigmen/scripts/haskell/qsort.hs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
qsort [] = []
|
||||||
|
qsort (p:ps) = (qsort (filter (\x -> x<=p) ps))
|
||||||
|
++ p:(qsort (filter (\x -> x> p) ps))
|
|
@ -0,0 +1,35 @@
|
||||||
|
Prelude> let x = \x -> x*x
|
||||||
|
Prelude> :t x
|
||||||
|
x :: Integer -> Integer
|
||||||
|
Prelude> x(2)
|
||||||
|
4
|
||||||
|
Prelude> x(2.2)
|
||||||
|
<interactive>:6:3:
|
||||||
|
No instance for (Fractional Integer)
|
||||||
|
arising from the literal `2.2'
|
||||||
|
Possible fix: add an instance declaration for
|
||||||
|
(Fractional Integer)
|
||||||
|
In the first argument of `x', namely `(2.2)'
|
||||||
|
In the expression: x (2.2)
|
||||||
|
In an equation for `it': it = x (2.2)
|
||||||
|
|
||||||
|
|
||||||
|
Prelude> let mult = \x y->x*y
|
||||||
|
Prelude> mult(2,5)
|
||||||
|
<interactive>:9:5:
|
||||||
|
Couldn't match expected type `Integer' with
|
||||||
|
actual type `(t0, t1)'
|
||||||
|
In the first argument of `mult', namely `(2, 5)'
|
||||||
|
In the expression: mult (2, 5)
|
||||||
|
In an equation for `it': it = mult (2, 5)
|
||||||
|
Prelude> mult 2 5
|
||||||
|
10
|
||||||
|
Prelude> :t mult
|
||||||
|
mult :: Integer -> Integer -> Integer
|
||||||
|
|
||||||
|
Prelude> let concat = \x y -> x ++ y
|
||||||
|
Prelude> concat [1,2,3] [3,2,1]
|
||||||
|
[1,2,3,3,2,1]
|
||||||
|
Prelude> :t concat
|
||||||
|
concat :: [a] -> [a] -> [a]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue