Haskell
Tags: Haskell, Programming, Programming Language
Sources: http://learnyouahaskell.com/chapters
Installation
Haskell Installation: Downloads
what do I need?:
- Stack
- ghc
- VS Code
Online Haskell
If online interpreter is needed: Haskell Playground
How to list
[ 1, 2, 3 ]
[ 1, 'ab' ]{ 2*x | x e N, x ≤ 10 }
[2x | x <- [1, 10], x ≤ 20]Der Abschnitt x←[1,10] ist der generierende Part
Der Abschnitt x ≤ 20 ist der filternde Teil
| Type | Input |
|---|---|
| Char | ‘a’ |
| String | “a” |
| Int (32bit) | |
| Double | |
| Bool | |
| Object | |
| List | [1, 2] |
| Tuple | (1, 2) |
ghci> [1,2,3] ++ [4,5][1,2,3,4,5]
ghci> head [1,2,3]1
ghci> tail [1,2,3][2,3]
ghci> 4 : [1,2,3][4,1,2,3]
ghci> [1 .. 10][1,2,3,4,5,6,7,8,9,10]
ghci> [1,3 .. 10][1,3,5,7,9]Exception Example

Math Equation examples
How to convert f(x, y) = x + y + 3.
f x y = x + y + 3f :: Int -> Int -> Int-- :: is of type-- the first Int is for x-- the second Int is for y-- the last Int is for the resultSmall Exercises
import Data.List (group)
-- doubleReverse: abcd -> abcddcbadoubleReverse :: [a] -> [a]doubleReverse x = x ++ reverse x
-- compr: Kompression "aaabbbcccca" -> [(3,'a'), (3,'b'), (4,'c'), (1,'a')]compr :: Eq a => [a] -> [(a, Int)]compr = map (\y -> (head y, length y)) . group
-- ggt: Größter gemeinsamer Teilerggt :: Integer -> Integer -> Integerggt a 0 = aggt a b = ggt b (a `mod` b)
factors :: Integer -> [Integer]factors n = [x | x <- [2 .. n - 1], n `mod` x == 0]
-- filterAdjacent: Filter einer Liste, wobei Element nur erhalten bleibt, wenn ident mit nachfolgendem, "abbbccd" -> "bbc"filterAdjacent :: Eq a => [a] -> [a]filterAdjacent = (init =<<) . group
-- isPal: Test auf Palindrom (Variante ohne Verwendung von reverse)isPal :: Eq a => [a] -> BoolisPal x = x == reverse xisPal' x = x == foldl (flip ( : )) [] x
-- isPrime: Test auf PrimzahlisPrime :: Integer -> BoolisPrime n = n > 1 && null (factors n)
-- isPowOfTwo: Test ob Zahl Potenz von 2 ist.isPowOfTwo :: Integer -> BoolisPowOfTwo 1 = TrueisPowOfTwo x | x < 1 = False | (x `mod` 2) /= 0 = False | x >= 2 = isPowOfTwo (x `div` 2)
-- kgv: Kleinstes gemeinsames Vielfacheskgv :: Integer -> Integer -> Integerkgv _ 0 = 0kgv 0 _ = 0kgv x y = abs ((x `quot` gcd x y) * y)
-- listPrime: Zwei Zahlen als Eingabe, alle Primzahlen dazwischen als AusgabelistPrime :: Integer -> Integer -> [Integer]listPrime l u = [x | x <- [l .. u], isPrime x]
-- primFaktorZerlegung: Ausgabe Liste von Tupel mit (Faktor, Anzahl), 144 -> [(2,4),(3,2)]primFaktorZerlegung :: Integer -> [(Integer, Int)]primFaktorZerlegung = compr . primeFactors
primeFactors n = case factor of [] -> [n] [f] -> factor ++ primeFactors (n `div` f) where factor = take 1 $ factors n
-- sums: [Int] -> [Int], n-te Zahl der Ausgabe = Summe der letzten n Zahlen der (endlichen) Eingabe, [1..5] -> [5,9,12,14,15]sums :: [Integer] -> [Integer]sums = scanl1 (+) . reverseGHCI Terminal
Imports
import Data.Map
import Data.Map as Mghci> M.map
import qualified Data.Map as MVerschiedene Funktionsaufruf Möglichkeiten
ghci> div 3 21ghci> 3 'div' 21ghci> (div) 3 21Check Typ von Funktion
ghci> f x = 2*xghci> :type f -- :t or :typef :: Num a => a -> aVerzweigung - If/else
ghci> f x = if x > 2 then ">2" else "<=2"ghci> :t ff :: (Ord a, Num a) => a -> Stringghci> f x = 2*xghci> f (if (f 2) > 3 then 1 else 3)2ghci> f 12Index
ghci> :t (!!)(!!) :: [a] -> Int -> aghci> (!!) [5,2,7] 05ghci> (!!) [5,2,7] 27Ordering - Compare
ghci> compare 3 2GT -- Greater Than
ghci> compare 2 2EQ -- Equal
ghci> compare 1 2LT -- Lesser ThanType Constraints
To display a type constraint in Haskell, you can use the :: operator.
For example, if you want to define a function add that takes two Int
arguments and returns an Int, you would write:
add :: Int -> Int -> Intadd x y = x + yIn this example, :: is used to specify that add takes two Int
arguments and returns an Int.
To specify a specific interface in a generic function:

maxBound
ghci> maxBound()
ghci> maxBound :: Int9223372036854775807
ghci> maxBound :: Char'\1114111'
ghci> maxBound :: OrderingGTConvert to String - show
ghci> show 3"3"
ghci> show [3]"[3]"
ghci> show ['a', 'b']"\"ab\""
ghci> putStrLn $ show "ab""ab"Convert from String - read
ghci> :t readread :: Read a => String -> a
ghci> read "3"*** Exception: Prelude.read: no parse -- Wirft exception, weil nicht weiß welcher Datentyp es werden soll.
ghci> read "3" :: Int3
ghci> read "True" :: BoolTruemap
ghci> :t mapmap :: (a -> b) -> [a] -> [b]
ghci> map show [1,2,3]["1", "2", "3"]
ghci> map (const 1) [1,2,3][1,1,1]
ghci> f x = x + 1
ghci> map f [1,2,3][2,3,4]
ghci> map (\x -> x * 2 + 1) [1,3,5][3,7,11]ghci> mymap f xs = foldr (\x acc -> f x : acc) [] xs
-- Point freestyleghci> mymap f = foldr ((:) . f) []
ghci> mymap succ [1,2,3]Filtering - filter
for
ghci> :t filterfilter :: (a -> Bool) -> [a] -> [a]
ghci> f x = x < 5
ghci> filter f [1 .. 10][1,2,3,4]Load Files
First create a txt. file and create a code snippet:
-- displays recursive functionf 0 = 0f x = 1 + f(x - 1)
-- shows an sum function with an unknown length listmysum [] = 0mysum (x:xs) = x + mysum xs
-- ---------------------------------------------------------- ---- own Maximum example with recursive check.mymax x y if x < y then y else x
mymaximum [] = error "will nicht"mymaximum [x] = xmymaximum (x:xs) = mymax x (mymaximum xs)Then go to a terminal, go to the correct path and open ghci.
ghci> :load file.hs[1 of 1] Compiling Main ( file.hs, interpreted )Ok, one module loaded.
ghci> mymaximum [2,5,3,6,7,1]7Zip

-- Catching Empty Listsmyzip [] _ = []myzip _ [] = []
myzip (x:xs) (y:ys) = (x,y):myzip xs ysQuicksort
Here’s an implementation of the quicksort algorithm in Haskell:
myquicksort [] = [] myquicksort (x:xs) = myquicksort (filter (< x) (x:xs)) ++ [x] ++ myquicksort (filter (> x) (x:xs))
This implementation sorts a list in ascending order.
Function application with $
f $ x = f x
ghci> map (+) [1,2,3][1+,2+,3+]
ghci> map ($ 1) [1,2,3][2,3,4]$ ermöglicht bessere Übersicht bei verketteten Abfragen
ghci> sum (filter (>10) (map (*2) [2..10]))
ghci> sum $ filter (>10) $ map (*2) $ [2..10]
ghci> f => \x -> sum $ filter (>10) $ map (*2) Xghci> f [2..10]80Function composition (.)

ghci> f = sum . filter (>10) . map (*2)ghci> f [2..10]80ghci> map (\x -> negate (abs x)) [...]
ghci> map (\x -> negate . abs $ x) [...]
ghci> map (negate . abs) [...]
-- ------------------------------------ghci> map (\xs -> negate (sum (tail xs))) [...]
ghci> map (\xs -> negate . sum(tail xs)) [...]
ghci> map (\xs -> negate . sum . tail $ xs) [...]
ghci> map (negate . sum . tail) [...]
-- ------------------------------------ghci> f = sum (takeWhile (<10000) (filter odd (map (^2) [1..])))
ghci> f = sum (takeWhile (<10000) (filter odd . map (^2) $ [1..]))
ghci> f = sum (takeWhile (<10000) . filter odd . map (^2) $ [1..])
ghci> f = sum . takeWhile (<10000) . filter odd . map (^2) $ [1..]Negate
ghci> negate . (* 3) $ 2-6ghci> negate . (* 3) 2-6ghci> negate $ (* 3) $ 2-6ghci> negate ( (* 3) 2 )-6ghci> negate (2* 3)-6My Elem
myelem x xs = foldl (\acc x -> if ((x==y) || acc) then True else False) False xsCesar Cipher

ghci> import Data.Charghci> ord 'a'97
ghci> chr '65''A'import Data.Char-- Ascii values 32 >= n < 127
-- encrypt "ein geheimer satz" 2encrypt :: [Char] -> Int -> Stringencrypt [] x = []encrypt (x:xs) n = shift x n : encrypt xs n
-- decrypt "ein verschlüsselter satz" 2decrypt :: [Char] -> Int -> Stringdecrypt x n = encrypt x (negate n)
-- shift 'a' 2 = 'c'shift :: Char -> Int -> Charshift x n = chr ((ord x + n) `mod` 127) -- 127 weil es 127 ASCII characters gibt
mapShift n x = chr ((ord x + n) `mod` 127) -- 127 weil es 127 ASCII characters gibt
mapEncrypt [] n = []mapEncrypt x n = map (mapShift n) xmapDecrypt x n = map (mapShift (negate n)) xMonaden
Aufgabe: Input entgegen nehmen, bissl modifizieren und ausgeben
-- returns the input text againghci> getLine >>= putStrLn
ghci> (getLine >>= putStrLn) >>= \x -> putStrLn "end"
-- getLine selber ohne inputghci> (return "abc" :: IO String) >>= putStrLn >>= \x -> putStrLn "end"abcend
-- falls typ genutzt wird, der nicht gebraucht wirdghci> putStrLn "hello" >> putStrLn "word"Return
Return verpackt etwas in einen Datentyp der gerade gebraucht wird
ghci> return "abc" :: [String]Lambda Kalkühl
λxy . x+y λx . (λy . x+y)
(λx . x+1) 2 = 2+1
(f o g) (x) = f(g(x)) o = λfgx -> f(gx) o = λfgx.f(gx)
ghci> :t (\x y z -> x)(\x y z -> x) :: p1 -> p2 -> p3 -> p1Group negative and positive
ghci> import Data.Listghci> let values = [-4.3,-2.4,-1.2,0.4,2.3,5.9,10.5,29.1,5.3,-2.4,-14.5,2.9,2.3]ghci> groupBy (\x y -> ((x >= 0) && (y >= 0)) || ((x < 0) && (y < 0))) values[[-4.3,-2.4,-1.2],[0.4,2.3,5.9,10.5,29.1,5.3],[-2.4,-14.5],[2.9,2.3]]
-- vereinfachungghci> groupBy (\x y -> ((x >= 0) == (y >= 0))) values[[-4.3,-2.4,-1.2],[0.4,2.3,5.9,10.5,29.1,5.3],[-2.4,-14.5],[2.9,2.3]]
-- vereinfachung mit onghci> import Data.Functionsghci> groupBy ((==) on (>=0)) values[[-4.3,-2.4,-1.2],[0.4,2.3,5.9,10.5,29.1,5.3],[-2.4,-14.5],[2.9,2.3]]| x | y | Result |
|---|---|---|
| + | + | True |
| + | - | False |
| - | + | False |
| - | - | True |
Network Domain WhoIs
import Network.Simple.TCP (connect, send, recv)import qualified Data.ByteString as BSimport System.IO (hFlush, stdout)
main = do putStr "Domain name: " hFlush stdout --durch puffern kann der string vllt erst nach getline ausgegeben werden domain <- BS.getLine -- returnt bytestring connect "whois.nic.at" "43" $ \(socket, _) -> do send socket domain mbs <- recv socket 4096 case mbs of Nothing -> return() Just bs -> BS.putStrLn bs