Tags: Haskell, Programming, Programming Language
Sources: http://learnyouahaskell.com/chapters
Haskell Installation: Downloads
what do I need?:
- Stack
- ghc
- VS Code
If online interpreter is needed: Haskell Playground
[ 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]
How to convert f(x, y) = x + y + 3
.
f x y = x + y + 3
f :: Int -> Int -> Int
-- :: is of type
-- the first Int is for x
-- the second Int is for y
-- the last Int is for the result
import Data.List (group)
-- doubleReverse: abcd -> abcddcba
doubleReverse :: [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 Teiler
ggt :: Integer -> Integer -> Integer
ggt a 0 = a
ggt 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] -> Bool
isPal x = x == reverse x
isPal' x = x == foldl (flip ( : )) [] x
-- isPrime: Test auf Primzahl
isPrime :: Integer -> Bool
isPrime n = n > 1 && null (factors n)
-- isPowOfTwo: Test ob Zahl Potenz von 2 ist.
isPowOfTwo :: Integer -> Bool
isPowOfTwo 1 = True
isPowOfTwo x
| x < 1 = False
| (x `mod` 2) /= 0 = False
| x >= 2 = isPowOfTwo (x `div` 2)
-- kgv: Kleinstes gemeinsames Vielfaches
kgv :: Integer -> Integer -> Integer
kgv _ 0 = 0
kgv 0 _ = 0
kgv x y = abs ((x `quot` gcd x y) * y)
-- listPrime: Zwei Zahlen als Eingabe, alle Primzahlen dazwischen als Ausgabe
listPrime :: 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 (+) . reverse
import Data.Map
import Data.Map as M
ghci> M.map
import qualified Data.Map as M
ghci> div 3 2
1
ghci> 3 'div' 2
1
ghci> (div) 3 2
1
ghci> f x = 2*x
ghci> :type f -- :t or :type
f :: Num a => a -> a
ghci> f x = if x > 2 then ">2" else "<=2"
ghci> :t f
f :: (Ord a, Num a) => a -> String
ghci> f x = 2*x
ghci> f (if (f 2) > 3 then 1 else 3)
2
ghci> f 1
2
ghci> :t (!!)
(!!) :: [a] -> Int -> a
ghci> (!!) [5,2,7] 0
5
ghci> (!!) [5,2,7] 2
7
ghci> compare 3 2
GT -- Greater Than
ghci> compare 2 2
EQ -- Equal
ghci> compare 1 2
LT -- Lesser Than
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 -> Int
add x y = x + y
In 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:
Type Constraintsghci> maxBound
()
ghci> maxBound :: Int
9223372036854775807
ghci> maxBound :: Char
'\1114111'
ghci> maxBound :: Ordering
GT
ghci> show 3
"3"
ghci> show [3]
"[3]"
ghci> show ['a', 'b']
"\"ab\""
ghci> putStrLn $ show "ab"
"ab"
ghci> :t read
read :: 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" :: Int
3
ghci> read "True" :: Bool
True
ghci> :t map
map :: (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 freestyle
ghci> mymap f = foldr ((:) . f) []
ghci> mymap succ [1,2,3]
for
ghci> :t filter
filter :: (a -> Bool) -> [a] -> [a]
ghci> f x = x < 5
ghci> filter f [1 .. 10]
[1,2,3,4]
First create a txt. file and create a code snippet:
-- displays recursive function
f 0 = 0
f x = 1 + f(x - 1)
-- shows an sum function with an unknown length list
mysum [] = 0
mysum (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] = x
mymaximum (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]
7
-- Catching Empty Lists
myzip [] _ = []
myzip _ [] = []
myzip (x:xs) (y:ys) = (x,y):myzip xs ys
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.
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) X
ghci> f [2..10]
80
ghci> f = sum . filter (>10) . map (*2)
ghci> f [2..10]
80
ghci> 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..]
ghci> negate . (* 3) $ 2
-6
ghci> negate . (* 3) 2
-6
ghci> negate $ (* 3) $ 2
-6
ghci> negate ( (* 3) 2 )
-6
ghci> negate (2* 3)
-6
myelem x xs = foldl (\acc x -> if ((x==y) || acc) then True else False) False xs
ghci> import Data.Char
ghci> ord 'a'
97
ghci> chr '65'
'A'
import Data.Char
-- Ascii values 32 >= n < 127
-- encrypt "ein geheimer satz" 2
encrypt :: [Char] -> Int -> String
encrypt [] x = []
encrypt (x:xs) n = shift x n : encrypt xs n
-- decrypt "ein verschlüsselter satz" 2
decrypt :: [Char] -> Int -> String
decrypt x n = encrypt x (negate n)
-- shift 'a' 2 = 'c'
shift :: Char -> Int -> Char
shift 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) x
mapDecrypt x n = map (mapShift (negate n)) x
Aufgabe: Input entgegen nehmen, bissl modifizieren und ausgeben
-- returns the input text again
ghci> getLine >>= putStrLn
ghci> (getLine >>= putStrLn) >>= \x -> putStrLn "end"
-- getLine selber ohne input
ghci> (return "abc" :: IO String) >>= putStrLn >>= \x -> putStrLn "end"
abc
end
-- falls typ genutzt wird, der nicht gebraucht wird
ghci> putStrLn "hello" >> putStrLn "word"
Return verpackt etwas in einen Datentyp der gerade gebraucht wird
ghci> return "abc" :: [String]
λ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 -> p1
ghci> import Data.List
ghci> 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]]
-- vereinfachung
ghci> 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 on
ghci> import Data.Functions
ghci> 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 |
import Network.Simple.TCP (connect, send, recv)
import qualified Data.ByteString as BS
import 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