-- definisanje liste (lista i jeste "ispod zita" funkcija)
l1 = [3,3,5]

{--
Main> head l1
3
Main> tail l1
[3,5]
Main> l1 !! 2
5
-}

{--
Main> :type l1
l1 :: [Integer]
Main> :type head
head :: [a] -> a
Main> 
-}

l2 = [['a'],['b','c']] 

l3 = [("String",435),("String2",454)]

-- eksplicitno dodeljivanje tipa funkciji
add1 :: Integer->Integer->Integer
add1 x y = x+y

-- ako ne navedemo eksplicitno, onda ce haskell sam 
-- da pokusa da dodeli tip preslikvanja
-- lista se interno predstavlja kao kompozicija funkcije :  i konstantih funkcija. 
-- npr. [4,5,6,3] = 4:(5:(6:3:[])) 

-- ovu internu reprezentaciju mozemo koristiti da bismo dekomponovali 
-- listu (najcecse je razbijamo u obliku glava-rep odnosno x:xs)
len [] = 0
len (x:xs) = 1+len(xs)
 
eliminisi [] min max = []
eliminisi (x:xs) min max = if (x>min && x<max) 
then (eliminisi xs min max) else x:(eliminisi xs min max)
 
posl [x] = x
posl (x:xs) = posl xs

pripada el [] = False
pripada el (x:xs) = if el==x then True else pripada el xs

-- [1,2,3,4]:
-- Potproblem: mi znamo od [2,3,4] da dobijemo 432
-- Svodjenje na celo resenje = 432*10+1
broj1 [] = 0
broj1 (x:xs) = (broj1 xs)*10+x

-- [1,2,3,4] -> 1234
broj2p [] a = a
broj2p (x:xs) a = broj2p xs a*10+x

broj2 l = broj2p l 0

prosek l = fromIntegral (suma l) / (len l)
suma [] = 0
suma (x:xs) = x+(suma xs)

-- ovo je isto sto i ugradjena infiksna funkcija ++ npr. [21,3]++[3,4]
spoji [] l = l
spoji (x:xs) l = x:(spoji xs l)

obrni [] = []
obrni (x:xs) = (obrni xs)++[x]

sufiksi [] = [[]]
sufiksi (x:xs) = (x:xs):(sufiksi xs)

-- generisanje skupova
s1 = [x^2 | x<-[1,5..59]]

s2 = [(x,y,x+y) | x<-[1..10], y<-[1,3..20]]

obrisizagrade xss = [x|xs<-xss,x<-xs]

prosti n = [x | x<-[2..n], [y | y<-[1..x], x `mod` y == 0]==[1,x]]

s3 = [(x,y,x+y) | (x,y)<-(zip [1..10] [1,3..20])]

pitagora n = [(x,y,z)| x<-[1..n],y<-[1..n],z<-[1..n],x^2+y^2==z^2]

skalarni l1 l2 = sum [x*y | (x,y)<-(zip l1 l2)]
