{- Elm diasor program Készítette: Hegedűs Dénes -} import Graphics.Input (Input, input, button) import Window import Mouse import Keyboard {- Főprogram, több jelet is felhasznál: currentPage.signal - aktuális oldal jele, azaz épp melyik oldalon állunk Window.dimensions - jel a böngésző felbontására Mouse.position - egér aktuális pozíciója count Mouse.clicks - egérkattintások száma a program indításától kezdve foldp ballStep ballState ballInput - a labda program jele, a labda állapotát (ballState) a bemenettől (ballInput) függően lépteti (ballStep) -} main : Signal Element main = scene <~ currentPage.signal ~ Window.dimensions ~ Mouse.position ~ count Mouse.clicks ~ foldp ballStep ballState ballInput -- aktuális oldal jelének kezdőállapota, tartalmaz egy Int értéket, ami az oldal száma currentPage : Input Int currentPage = input 0 {- A teljes program megjelenítése 2 réteggel: a dia aktuális oldala (content ...) fent és léptető gombok lent, paramétereit a main függvényben használt jelek értékéből kapja, amiket a (<~) és (~) operátorok olvasnak ki -} scene : Int -- aktuális oldalszám -> (Int,Int) -- böngésző felbontása -> (Int,Int) -- egér pozíciója -> Int -- kattintások száma -> Position Float -- pötty pozíciója -> Element scene num (w,h) mouse clicks ball = layers [ container w h midTop <| content num (w,h) mouse clicks ball -- fent: aktuális oldal , container w h midBottom <| color lightOrange <| flow right -- lent: gombok [ container 100 40 middle <| button currentPage.handle (num - 1) "<" -- balra , container 100 40 middle <| plainText (" " ++ (show (num + 1)) ++ " / 20 ") -- aktuális oldalszám , container 100 40 middle <| button currentPage.handle (num + 1) ">" -- jobbra ] ] {- Faktoriális számítás -} fac : Int -> Int fac n = if n <= 1 then 1 else n * fac (n-1) {- Nyilakkal mozgatható labda programja -} -- pozíció típusa type Position a = { x : a, y : a } -- kezdőállapot ballState : Position Float ballState = { x = 0, y = 0 } -- lépés ballStep : Position Int -> Position Float -> Position Float ballStep dir st = { st | x <- st.x + toFloat dir.x * 3 , y <- st.y + toFloat dir.y * 3 } -- megjelenítés ballDisplay : Position Float -> Element ballDisplay {x,y} = collage 100 500 [ move (x,y) (filled blue (oval 30 30)) ] -- bemenet, azaz a billentyűzet mintavételezése ballInput = sampleOn (fps 30) Keyboard.arrows {- Diasor a formázást html "markdown" segíti, aminek szintaxisa: [markdown||] -} -- cím formázása toTitle str = centered <| typeface ["futura", "century gothic", "twentieth century", "calibri", "verdana", "helvetica", "arial"] <| Text.height 60 <| (toText str) -- a diasort megjelenítő függvény content : Int -> (Int,Int) -> (Int,Int) -> Int -> Position Float -> Element content n (w,h) mouse clicks ball = let -- oldal megjelenítése 2 réteggel: cím (toTitle title), tartalom (content) page title content = layers [ container w h midTop <| color lightGreen <| toTitle title , container w h middle <| content ] in case n of 1 -> page "elm" <| [markdown|
- webes GUI-kat szeretnénk
tömören leírni - JavaScript túl költséges - Evan Czaplicki, Prezi
|] 2 -> page "elm" <| [markdown|
- 2011-ben jelent meg - interaktív webes alkalmazások
minimális kódból - fordító / webszerver - JS, HTML és CSS-re fordul - fejlesztés alatt áll, v0.12
|] 3 -> page "elm" [markdown|
- tisztán funkcionális nyelv - Haskell-szerű, szűkebb - margószabályos - statikusan típusos - típuskikövetkeztés
|] 4 -> page "hello" <| flow down [ flow right [ container 400 100 midLeft <| [markdown|
main : Element
main =
 plainText "Hello 娑婆!"
|] , color lightGray <| container 300 100 middle <| plainText "Hello 娑婆!" ] , spacer 0 25 , flow right [ container 400 150 midLeft <| [markdown|
fac : Int -> Int
fac n =
 if n <= 1 then 1
 else n * fac (n-1)
|] , color lightGray <| container 300 150 middle <| centered <| Text.height 20 <| toText ("fac 100 = " ++ show (fac 100)) -- faktoriális program beágyazása ] ] 5 -> page "alap" [markdown|
3.14  : Float

'a'   : Char
"abc" : String

data Bool = True | False

True  : Bool
False : Bool
|] 6 -> page "lista" [markdown|
Ezek ekvivalensek:
[1..4]
[1,2,3,4]
1 :: [2,3,4]
1 :: 2 :: 3 :: 4 :: []
|] 7 -> page "függvények" [markdown|
f : Int -> Int
f x = x * x

g = \x -> x * x
- egy függvénynek csak egy törzse lehet - paraméterre nincs mintaillesztés
|] 8 -> page "if" [markdown|
Egy ágú if:
if status == Ok then "ok" else "not ok"
Több ágú if:
if | status == Ok -> "ok"
   | ...
   | otherwise    -> "not ok"
Mintaillesztés:
case status of
  Ok -> "ok"
  ...
  _  -> "not ok"
|] 9 -> page "dia dia" <| flow right [ container 560 200 midLeft <| [markdown|
main = layers
  [ fittedImage 320 240 "logo.png"
  , width 320 <| plainText "cím"
  , container 320 240 middle <|
      plainText "tartalom"
  ]
|] , color lightGray <| container 200 200 middle <| (layers [ fittedImage 200 200 "logo.png" , width 200 <| centered <| toText "cím" , container 200 200 middle <| plainText "tartalom" ]) ] 10 -> page "frp" [markdown|
- funkcionális reaktív programozás (FRP) - 1997-ben jelent meg - eredetileg animációkra - idő és események modellezésére
|] 11 -> page "main" [markdown|
Statikus:
main : Element
Változó:
main : Signal Element
|] 12 -> page "frp" <| flow down [ flow right [ container 500 100 midLeft <| [markdown|
main : Signal Element
main =
 asText <~ Mouse.position
|] , color lightGray <| container 250 100 middle <| centered <| Text.height 50 <| toText (show mouse) -- egérpozíció program beágyazása ] , spacer 0 25 , flow right [ container 500 100 midLeft <| [markdown|
main : Signal Element
main =
 asText <~ count Mouse.clicks
|] , color lightGray <| container 250 100 middle <| centered <| Text.height 50 <| toText ("clicks: " ++ show clicks) -- egérkattintások beágyazása ] ] 13 -> page "signal" [markdown|
Minden kattintásnál kiváltódik:
Mouse.clicks : Signal ()
Megmondja, hogy hányszor váltódott ki:
count : Signal a -> Signal Int
|] 14 -> page "signal" [markdown|
Tiszta függvényeket be tudunk emelni jelekbe:
a <~ b = lift a b
lift : (a -> b) -> Signal a -> Signal b
Ezzel tudjuk a jeleket módosítani, pl. kirajzolható elemmé
|] 15 -> page "record" [markdown|
- JavaScript-hez hasonló rekordok - kibővíthetőek új mezőkkel:
addName : String -> a -> { a | name:String }
addName name record = { record | name = name }
|] 16 -> page "pötty" <| flow right [ container 600 500 midLeft <| [markdown|
state = { x = 0, y = 0 }

step dir st =
 { st | x <- st.x + toFloat dir.x * 3
      , y <- st.y + toFloat dir.y * 3 }

display {x,y} =
 collage 100 500
  [ move (x,y) (filled blue (oval 30 30)) ]

input = sampleOn (fps 30) Keyboard.arrows
main = lift display (foldp step state input)
|] , color lightGray <| container 100 500 middle <| ballDisplay ball -- labda program beágyazása ] 17 -> page "let" [markdown|
let
  x = 42
  square n = n * n
  ...
in
  square x
|] 18 -> page "ami nincs" [markdown|
Amit nem támogat a nyelv: - operátor szeletek (+2), (<3) - őrfeltételek (guarded definitions)
helyette if - do notáció - egy függvénynek több törzs - kivételek
|] 19 -> page "kérdések" [markdown|
- Mi lehet a main függvény típusa? - Hogyan tudunk jeleket (Signal a) módosítani? - Miben különböznek a függvénydeklarációk a
Haskell-ben lévőktől?
|] _ -> page "elm" <| flow down [ (image 300 300 "logo.png") , container 300 100 middle <| centered <| Text.height 40 <| toText ("Hegedűs Dénes") ]