mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-11-22 12:32:09 +03:00
Merge pull request #3748 from mstou/gr-haskell
[haskell/el-gr] Add Greek translation for Haskell
This commit is contained in:
commit
bb8186e72b
476
el-gr/haskell-gr.html.markdown
Normal file
476
el-gr/haskell-gr.html.markdown
Normal file
@ -0,0 +1,476 @@
|
||||
---
|
||||
language: Haskell
|
||||
filename: haskell-gr.html.markdown
|
||||
contributors:
|
||||
- ["Miltiadis Stouras", "https://github.com/mstou"]
|
||||
---
|
||||
|
||||
Η Haskell σχεδιάστηκε για να είναι μια πρακτική, αγνή συναρτησιακή γλώσσα προγραμματισμού.
|
||||
Είναι διάσημη για τα monads και το σύστημα τύπων της, αλλά χρησιμοποιείται από πολλούς
|
||||
κυρίως για την κομψότητά της. Προσωπικά θεωρώ ότι είναι από τις πιο όμορφες, αν όχι
|
||||
η πιο όμορφη, γλώσσα προγραμματισμού.
|
||||
|
||||
```haskell
|
||||
-- Τα σχόλια μιας γραμμής ξεκινούν με 2 παύλες.
|
||||
{- Ενώ τα σχόλια πολλών γραμμών βρίσκονται
|
||||
μέσα σε blocks σαν αυτό
|
||||
-}
|
||||
|
||||
----------------------------------------------------
|
||||
-- 1. Πρωτόγονοι Τύποι Δεδομένων (Primitive datatype) και Τελεστές
|
||||
----------------------------------------------------
|
||||
|
||||
-- Οι αριθμοί είναι ένα primitive datatype
|
||||
3 -- 3
|
||||
|
||||
-- Και οι τελεστές κάνουν αυτό που θα περιμέναμε
|
||||
1 + 1 -- 2
|
||||
8 - 1 -- 7
|
||||
10 * 2 -- 20
|
||||
35 / 5 -- 7.0
|
||||
|
||||
-- Η καθιερωμένη διαίρεση δεν είναι ακέραια
|
||||
35 / 4 -- 8.75
|
||||
|
||||
-- Η ακέραια διαίρεση γίνεται με την συνάρτηση div
|
||||
35 `div` 4 -- 8
|
||||
|
||||
-- Και οι boolean μεταβλητές ειναι primitives
|
||||
True
|
||||
False
|
||||
|
||||
-- Πράξεις με booleans
|
||||
not True -- False
|
||||
not False -- True
|
||||
1 == 1 -- True
|
||||
1 /= 1 -- False
|
||||
1 < 10 -- True
|
||||
|
||||
-- Στα παραπάνω παραδείγματα, το `not` είναι μια συνάρτηση που παίρνει ένα όρισμα
|
||||
-- Στην Haskell δεν χρειάζονται παρενθέσεις για τις κλήσεις συναρτήσεων, όλες οι παράμετροι
|
||||
-- γράφονται με κενά αμέσως μετά την συνάρτηση. Στην γενική περίπτωση,
|
||||
-- η κλήση συνάρτησης μοιάζει κάπως έτσι: func arg1 arg2 arg3...
|
||||
-- Για το πως να ορίσετε τις δικές σας συναρτήσεις διαβάστε το κεφάλαιο των συναρτήσεων παρακάτω
|
||||
|
||||
-- Συμβολοσειρές και χαρακτήρες
|
||||
"This is a string." -- συμβολοσειρά
|
||||
'a' -- χαρακτήρας
|
||||
'You cant use single quotes for strings.' -- error!
|
||||
-- δεν μπορούμε να γράψουμε συμβολοσειρές ανάμεσα από ''
|
||||
|
||||
-- Οι συμβολοσειρές μπορούν να συννενωθούν με την χρήση του τελεστή ++
|
||||
"Hello " ++ "world!" -- "Hello world!"
|
||||
|
||||
-- Η συμβολοσειρά είναι ουσιαστικά μια λίστα χαρακτήρων
|
||||
['H', 'e', 'l', 'l', 'o'] -- "Hello"
|
||||
"This is a string" !! 0 -- 'T'
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
-- 2. Λίστες και διατεταγμένα σύνολα (tuples)
|
||||
----------------------------------------------------
|
||||
|
||||
-- Όλα τα στοιχεία μιας λίστας πρέπει να είναι του ίδιου τύπου
|
||||
-- Οι δύο παρακάτω λίστες είναι οι ίδιες:
|
||||
[1, 2, 3, 4, 5]
|
||||
[1..5] -- διάστημα ή range
|
||||
|
||||
-- Τα διαστήματα μπορούν να χρησιμοποιηθούν και για άλλους τύπους εκτός από αριθμούς
|
||||
['A'..'F'] -- "ABCDEF"
|
||||
|
||||
-- Μπορούμε ακόμη να ορίσουμε και ένα βήμα
|
||||
[0,2..10] -- [0, 2, 4, 6, 8, 10]
|
||||
[5..1] -- [] (Το default βήμα της Haskell είναι το 1, επομένως η διπλανή λίστα είναι κενή)
|
||||
[5,4..1] -- [5, 4, 3, 2, 1]
|
||||
|
||||
-- Προσπέλαση στοιχείου σε τυχαία θέση
|
||||
[1..10] !! 3 -- 4 (οι δείκτες των θέσεων ξεκινούν από το 0)
|
||||
|
||||
-- Στην Haskell υπάρχουν και άπειρες λίστες!
|
||||
[1..] -- η λίστα των φυσικών αριθμών
|
||||
|
||||
-- Οι άπειρες λίστες μπορούν να λειτουργούν επειδή η Haksell έχει "lazy evaluation".
|
||||
-- Αυτό σημαίνει ότι η Haskell κάνει υπολογισμούς μόνο όταν πραγματικά χρειάζεται!
|
||||
-- οπότε αν ζητήσουμε το 1000στό στοιχείο μιας άπειρης λίστας θα μας το δώσει,
|
||||
-- ξέρει ότι δεν χρειάζεται να υπολογίσει όλη την άπειρη λίστα πρώτα!
|
||||
|
||||
[1..] !! 999 -- 1000
|
||||
|
||||
-- Στο παραπάνω παράδειγμα η Haskell υπολόγισε τα στοιχεία 1 μέχρι 1000...τα υπόλοιπα
|
||||
-- στοιχεία της άπειρης λίστας δεν υπάρχουν ακόμα! Η Haskell θα τα υπολογίσει
|
||||
-- μόνο αν κάποια στιγμή τα χρειαστεί.
|
||||
|
||||
-- συνένωση δύο λιστών με τον τελεστή ++ (σε γραμμικό χρόνο)
|
||||
[1..5] ++ [6..10]
|
||||
|
||||
-- προσθήκη στοιχείου στην αρχή της λίστας (σε σταθερό χρόνο)
|
||||
0:[1..5] -- [0, 1, 2, 3, 4, 5]
|
||||
|
||||
-- περισσότερες συναρτήσεις για τις λίστες
|
||||
head [1..5] -- 1
|
||||
tail [1..5] -- [2, 3, 4, 5]
|
||||
init [1..5] -- [1, 2, 3, 4]
|
||||
last [1..5] -- 5
|
||||
|
||||
-- list comprehensions
|
||||
-- ένας άλλος τρόπος να ορίζουμε τις λίστες που θυμίζει πολύ τον ορισμό συνόλων στα μαθηματικά!
|
||||
[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
|
||||
|
||||
-- list comprehension με συνθήκη
|
||||
[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
|
||||
|
||||
-- Κάθε στοιχείο ενός tuple μπορεί να έχει διαφορετικό τύπο, όμως το tuple έχει σταθερό μέγεθος.
|
||||
-- Ένα tuple:
|
||||
("haskell", 1)
|
||||
|
||||
-- προσπέλαση στοιχείων ενός ζεύγους στοιχείων (δηλαδή ενός tuple μεγέθους 2)
|
||||
fst ("haskell", 1) -- "haskell"
|
||||
snd ("haskell", 1) -- 1
|
||||
|
||||
-- οι παραπάνω συναρτήσεις δεν λειτουργούν σε tuples μεγαλύτερου μεγέθους
|
||||
snd ("snd", "can't touch this", "da na na na") -- error!
|
||||
|
||||
----------------------------------------------------
|
||||
-- 3. Συναρτήσεις
|
||||
----------------------------------------------------
|
||||
-- Μια απλή συνάρτηση που παίρνει 2 μεταβλητές a, b και επιστρέφει το άθροισμά τους
|
||||
add a b = a + b
|
||||
|
||||
-- Προσέξτε ότι αν χρησιμοποιείτε το διαδραστικό περιβάλλον της Haskell (ghci), δηλαδή
|
||||
-- τον interpreter, θα πρέπει να προσθέσετε ενα `let` πριν τον ορισμό της συνάρτησης:
|
||||
-- let add a b = a + b
|
||||
|
||||
-- Κλήση της συνάρτησης
|
||||
add 1 2 -- 3
|
||||
|
||||
-- Μπορούμε να καλέσουμε την συνάρτηση και σαν τελεστή ανάμεσα στα 2 ορίσματα
|
||||
-- γράφοντας το όνομα της συνάρτησης μέσα σε backticks:
|
||||
1 `add` 2 -- 3
|
||||
|
||||
-- Μπορούμε να ορίσουμε και συναρτήσεις που δεν έχουν γράμματα στο όνομά τους!
|
||||
-- Αυτό μας επιτρέπει να ορίσουμε δικούς μας τελεστές, όπως για παράδειγμα την ακέραια διάιρεση:
|
||||
|
||||
(//) a b = a `div` b
|
||||
35 // 4 -- 8
|
||||
|
||||
-- Guards: ένας εύκολος τρόπος να υλοποιήσουμε διακλαδώσεις σε μια συνάρτηση
|
||||
fib x
|
||||
| x < 2 = 1
|
||||
| otherwise = fib (x - 1) + fib (x - 2)
|
||||
|
||||
-- Το ταίριασμα προτύπων (Pattern matching) είναι παρόμοιο.
|
||||
-- Εδώ δίνουμε 3 διαφορετικούς ορισμούς για την συνάρτηση fib
|
||||
-- H Haskell θα χρησιμοποιήσει αυτόματα τον πρώτο ορισμό το οποίου οι παράμετροι
|
||||
-- ταιριάζουν με τις παραμέτρους της κλήσης
|
||||
|
||||
fib 1 = 1
|
||||
fib 2 = 2
|
||||
fib x = fib (x - 1) + fib (x - 2)
|
||||
|
||||
-- Pattern matching σε tuples
|
||||
sndOfTriple (_, y, _) = y
|
||||
-- η κάτω παύλα χρησιμοποιείται για να μην δίνουμε ονόματα
|
||||
-- σε μεταβλητές που δεν θα χρησιμοποιήσουμε και
|
||||
-- ταιριάζει με όλους τους τύπους
|
||||
|
||||
-- Pattern matching σε λίστες.
|
||||
-- Στο παρακάτω παράδειγμα, το `x` είναι το πρώτο στοιχείο της λίστας
|
||||
-- και τo `xs` είναι η λίστα με τα υπόλοιπα στοιχεία
|
||||
|
||||
myMap func [] = []
|
||||
myMap func (x:xs) = func x : (myMap func xs)
|
||||
|
||||
-- Μπορούμε να ορίσουμε και ανώνυμες συναρτήσεις (lambdas) χρησιμοποιώντας το
|
||||
-- backslash (που μοιάζει με λ) ακολουθούμενο από τις παραμέτρους:
|
||||
myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
|
||||
|
||||
-- χρήση της συνάρτησης fold με μία ανώνυμη συνάρτηση
|
||||
-- Το foldl1 είναι σαν fold από αριστερά, αλλά χρησιμοποιεί σαν αρχική τιμή του
|
||||
-- accumulator το πρώτο στοιχείο της λίστας.
|
||||
foldl1 (\acc x -> acc + x) [1..5] -- 15
|
||||
|
||||
----------------------------------------------------
|
||||
-- 4. Περισσότερες συναρτήσεις
|
||||
----------------------------------------------------
|
||||
|
||||
-- Μερική κλήση: αν δεν περάσουμε όλες τις μεταβλητές σε μια συνάρτηση,
|
||||
-- τότε αυτή "καλείται μερικώς". Αυτό σημαίνει ότι μας επιστρέφει μια συνάρτηση
|
||||
-- η οποία παίρνει ως ορίσματα τις εναπομείνασες μεταβλητές
|
||||
|
||||
add a b = a + b
|
||||
foo = add 10 -- η foo είναι μια συνάρτηση που περιμένει 1 αριθμό και του προσθέτει 10
|
||||
foo 5 -- 15
|
||||
|
||||
-- Ένας άλλος τρόπος να γράψουμε το ίδιο πράγμα:
|
||||
foo = (10+)
|
||||
foo 5 -- 15
|
||||
|
||||
-- Σύνθεση συναρτήσεων
|
||||
-- Ο τελεστής `.` χρησιμοποιείται για την σύνθεση ("αλυσίδωση") συναρτήσεων.
|
||||
-- Για παράδειγμα, η foo παρακάτω είναι μια συνάρτηση που παίρνει ως όρισμα 1 αριθμό.
|
||||
-- Πρώτα προσθέτει 10 στον αριθμό που δώσαμε και μετά πολλαπλασιάζει το αποτέλεσμα με 4
|
||||
foo = (4*) . (10+)
|
||||
|
||||
-- 4*(10+5) = 60
|
||||
foo 5 -- 60
|
||||
|
||||
-- διόρθωση προτεραιότητας
|
||||
-- Στην Haskell υπάρχει ο τελεστής `$`. Ο τελεστής αυτός εφαρμόζει μια συνάρτηση
|
||||
-- σε μία παράμετρο. Σε αντίθεση με την απλή εφαρμογή συνάρτησης, η οποία έχει
|
||||
-- την μεγαλύτερη πιθανή προτεραιότητα και είναι αριστερά προσεταιριστική,
|
||||
-- ο τελεστής `$` έχει την ελάχιστη προτεραιότητας και είναι δεξιά προσεταιριστικός.
|
||||
-- Λόγω της χαμηλής του προτεραιότητας, η έκφραση που βρίσκεται στα δεξιά του
|
||||
-- θα υπολογιστεί και θα περαστεί σαν παράμετρος στην συνάρτηση που βρίσκεται στα αριστερά του
|
||||
|
||||
|
||||
-- πριν
|
||||
even (fib 7) -- false
|
||||
|
||||
-- ισοδύναμα
|
||||
even $ fib 7 -- false
|
||||
|
||||
-- χρησιμοποιόντας σύνθεση συναρτήσεων
|
||||
even . fib $ 7 -- false
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
-- 5. Τύποι
|
||||
----------------------------------------------------
|
||||
|
||||
-- Η Haskell έχει ένα πολύ ισχυρό σύστημα τύπων, στο οποίο κάθε έκφραση έχει έναν τύπο
|
||||
|
||||
-- Κάποιο βασικοί τύποι:
|
||||
5 :: Integer
|
||||
"hello" :: String
|
||||
True :: Bool
|
||||
|
||||
-- Και οι συναρτήσεις έχουν κάποιο τύπο
|
||||
-- Η συνάρτηση`not` παίρνει ένα boolean και επιστρέφει ένα boolean:
|
||||
-- not :: Bool -> Bool
|
||||
|
||||
-- Παρακάτω βλέπετε μια συνάρτηση που παίρνει 2 ορίσματα:
|
||||
-- add :: Integer -> Integer -> Integer
|
||||
|
||||
-- Όταν ορίζουμε μια συνάρτηση ή μεταβλητή, είναι καλή πρακτική να γράφουμε
|
||||
-- και τον τύπο της:
|
||||
double :: Integer -> Integer
|
||||
double x = x * 2
|
||||
|
||||
----------------------------------------------------
|
||||
-- 6. Έλεγχος ροής και συνθήκες
|
||||
----------------------------------------------------
|
||||
|
||||
-- if-expressions
|
||||
haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
|
||||
|
||||
-- τα if-expressions μπορούν να πιάνουν και πολλές γραμμές
|
||||
-- αλλά η στοίχιση είναι σημαντική!
|
||||
haskell = if 1 == 1
|
||||
then "awesome"
|
||||
else "awful"
|
||||
|
||||
-- case expressions: Με τον παρακάτω τρόπο θα μπορούσαμε να κάνουμε parse
|
||||
-- command line arguments
|
||||
case args of
|
||||
"help" -> printHelp
|
||||
"start" -> startProgram
|
||||
_ -> putStrLn "bad args"
|
||||
|
||||
-- Η Haskell δεν έχει βρόχους επανάληψης; αντιθέτως, χρησιμοποιούμε αναδρομή.
|
||||
-- Η συνάρτηση map εφαρμόζει μια συνάρτηση σε κάθε στοιχείο μιας λίστας
|
||||
|
||||
map (*2) [1..5] -- [2, 4, 6, 8, 10]
|
||||
|
||||
-- μπορούμε να κατασκευάσουμε τον βρόχο for χρησιμοποιώντας την map
|
||||
for array func = map func array
|
||||
|
||||
-- και να τον χρησιμοποιήσουμε
|
||||
for [0..5] $ \i -> show i
|
||||
|
||||
-- το παραπάνω θα μπορούσε να γραφτεί και έτσι:
|
||||
for [0..5] show
|
||||
|
||||
-- Μπορούμε να χρησιμοποιήσουμε τις συναρτήσεις foldl και foldr
|
||||
-- για να υπολογίζουμε μια τιμή από μια λίστα (πχ άθροισμα ή γινόμενο)
|
||||
-- foldl <fn> <initial value> <list>
|
||||
foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
|
||||
|
||||
-- Η παραπάνω κλήση είναι η ίδια με:
|
||||
(2 * (2 * (2 * 4 + 1) + 2) + 3)
|
||||
|
||||
-- Η foldl γίνεται από τα αριστερά ενώ η foldr από τα δεξιά
|
||||
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
|
||||
|
||||
-- Η παραπάνω κλήση είναι τώρ:
|
||||
(2 * 1 + (2 * 2 + (2 * 3 + 4)))
|
||||
|
||||
----------------------------------------------------
|
||||
-- 7. Τύποι δεδομένων
|
||||
----------------------------------------------------
|
||||
|
||||
-- Με τον παρακάτω τρόπο μπορούμε να ορίζουμε δικούς μας τύπους
|
||||
-- δεδομένων στην Haskell
|
||||
|
||||
data Color = Red | Blue | Green
|
||||
|
||||
-- Τώρα μπορούμε να χρησιμοποιήσουμε τον τύπο μας και σε συναρτήσεις:
|
||||
|
||||
say :: Color -> String
|
||||
say Red = "You are Red!"
|
||||
say Blue = "You are Blue!"
|
||||
say Green = "You are Green!"
|
||||
|
||||
-- Οι τύποι δεδομένων μας μπορεί να είναι και παραμετρικοί, να δέχονται δηλαδή
|
||||
-- κάποιον τύπο ως παράμετρο
|
||||
|
||||
data Maybe a = Nothing | Just a
|
||||
|
||||
-- Όλες οι παρακάτω τιμές έχουν τύπο Maybe
|
||||
Just "hello" -- of type `Maybe String`
|
||||
Just 1 -- of type `Maybe Int`
|
||||
Nothing -- of type `Maybe a` for any `a`
|
||||
|
||||
----------------------------------------------------
|
||||
-- 8. Haskell IO
|
||||
----------------------------------------------------
|
||||
|
||||
-- Αν και το IO δεν μπορεί να εξηγηθεί σε βάθος χωρίς να εξηγήσουμε
|
||||
-- πρώτα τα monads, δεν είναι δύσκολο να το εξηγήσουμε αρκετά ώστε να μπορεί
|
||||
-- κάποιος να το χρησιμοποιήσει
|
||||
|
||||
-- Όταν ένα πρόγραμμα Haskell εκτελείται, καλείται η συνάρτηση `main`
|
||||
-- Η συνάρτηση αυτή πρέπει να επιστρέφει τύπο `IO a` για κάποιο τύπο `a`.
|
||||
-- Για παράδειγμα:
|
||||
|
||||
main :: IO ()
|
||||
main = putStrLn $ "Hello, sky! " ++ (say Blue)
|
||||
-- η συνάρτηση putStrLn έχει τύπο: String -> IO ()
|
||||
|
||||
-- Είναι πιο εύκολο να χρησιμοποιήσουμε IO αν μπορούμε να γράψουμε το πρόγραμμά μας
|
||||
-- ως μια συνάρτηση από String σε String. Η συνάρτηση
|
||||
-- interact :: (String -> String) -> IO ()
|
||||
-- παίρνει ως είσοδο ένα string, τρέχει μια συνάρτηση πάνω στην είσοδο
|
||||
-- και τυπώνει την έξοδο
|
||||
|
||||
countLines :: String -> String
|
||||
countLines = show . length . lines
|
||||
|
||||
main' = interact countLines
|
||||
|
||||
-- Μπορείτε να σκεφτείτε μια συνάρτηση που επιστρέφει τιμή με τύπο `IO ()`
|
||||
-- ως μια ακολουθία πράξεων, περίπου όπως και σε μια imperative γλώσσα
|
||||
-- Μπορούμε να χρησιμοποιήσουμε το `do` και να ενώσουμε αυτές τις κλήσεις
|
||||
-- Για παράδειγμα:
|
||||
|
||||
sayHello :: IO ()
|
||||
sayHello = do
|
||||
putStrLn "What is your name?"
|
||||
name <- getLine -- η συνάρτηση αυτή διαβάζει μια γραμμή και την αναθέτει στην μετβαλήτη name
|
||||
putStrLn $ "Hello, " ++ name
|
||||
|
||||
-- Δοκιμάστε να γράψετε την συνάρτηση `interact` που θα διαβάζει μια γραμμή
|
||||
|
||||
-- Ωστόσο ο κώδικας της συνάρτησης `sayHello` δεν θα εκτελεστεί ποτέ. Η μόνη συνάρτηση
|
||||
-- που εκτελείται όταν κάνουμε compile ένα αρχείο haskell είναι η `main`.
|
||||
-- Αν θέλετε να τρέξετε την sayHello (εκτός από το να φορτώσετε τον κώδικα στο
|
||||
-- ghci) μπορείτε να βάλετε σε σχόλια τον προηγούμενο ορισμό της main
|
||||
-- και να την ορίσετε ως:
|
||||
-- main = sayHello
|
||||
|
||||
-- Ας προσπαθήσουμε να καταλάβουμε πως λειτουργεί η συνάρτηση `getLine`
|
||||
-- Ο τύπος της είναι:
|
||||
-- getLine :: IO String
|
||||
-- Μπορείτε να φανταστείτε ότι μια τιμή με τύπο `IO a` θα παραχθεί
|
||||
-- από ένα πρόγραμμα που παράγει μια τιμή με τύπο `a` (ενώ παράλληλα κάνει και κάτι άλλο)
|
||||
-- Μπορούμε να πάρουμε και να επαναχρησιμοποιήσουμε αυτήν την τιμή χρησιμοποιώντας
|
||||
-- το `<-`. Μπορούμε ακόμα και να φτιάξουμε την δική μας συνάρτηση με τύπο
|
||||
-- `IO String`:
|
||||
|
||||
action :: IO String
|
||||
action = do
|
||||
putStrLn "This is a line. Duh"
|
||||
input1 <- getLine
|
||||
input2 <- getLine
|
||||
-- Ο τύπος του `do` μπλοκ είναι εκείνος της τελευταίας γραμμής.
|
||||
-- Το `return` δεν είναι κάποια ειδική λέξη, αλλά απλώς μια συνάρτηση
|
||||
return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
|
||||
|
||||
-- Μπορούμε να χρησιμοποιήσουμε την παραπάνω συνάρτηση ακριβώς όπως την `getLine`:
|
||||
|
||||
main'' = do
|
||||
putStrLn "I will echo two lines!"
|
||||
result <- action
|
||||
putStrLn result
|
||||
putStrLn "This was all, folks!"
|
||||
|
||||
-- Ο τύπος `IO` είναι παράδειγμα ενός "monad". Χρησιμοποιώντας τα monads για το
|
||||
-- ΙΟ, η Haskell καταφέρνει να είναι αγνή συναρτησιακή γλώσσα. Κάθε συνάρτηση που
|
||||
-- αλληλεπιδρά με τον έξω κόσμο (δηλαδή κάνει IO), έχει το IO (ή κάποιο άλλο monad)
|
||||
-- στον τύπο της. Αυτό μας διευκολύνει να γνωρίζουμε ποιές συναρτήσεις είναι αγνές
|
||||
-- (μαθηματικές -- δεν αλληλεπιδρούν με τον έξω κόσμο ούτε αλλάζουν κάποιο state)
|
||||
-- και ποιες δεν είναι.
|
||||
|
||||
-- Αυτό είναι ένα πολύ ισχυρό χαρακτηριστικό γιατί είναι πολύ εύκολο να
|
||||
-- εκτελούμε παράλληλα αγνές συναρτήσεις! Οπότε η παραλληλοποίηση στην Haskell
|
||||
-- είναι αρκετά πιο εύκολη
|
||||
|
||||
----------------------------------------------------
|
||||
-- 9. Haskell REPL
|
||||
----------------------------------------------------
|
||||
|
||||
-- Μπορείτε να ξεκινήσετε το διαδραστικό περιβάλλον της Haskell με την εντολή `ghci`.
|
||||
-- Εδώ μπορείτε να γράψετε και να εκτελέσετε κώδικα haskell.
|
||||
-- Κάθε νέα τιμή πρέπει να ορίζεται με το `let`
|
||||
|
||||
let foo = 5
|
||||
|
||||
-- Μπορείτε να βρείτε τον τύπο μιας συνάρτησης με το `:t`:
|
||||
|
||||
> :t foo
|
||||
foo :: Integer
|
||||
|
||||
-- Οι τελεστές, όπως οι `+`, `:` και `$`, είναι επίσης συναρτήσεις.
|
||||
-- Μπορούμε να δούμε τον τύπο τους βάζοντας τους μέσα σε παρενθέσεις:
|
||||
|
||||
> :t (:)
|
||||
(:) :: a -> [a] -> [a]
|
||||
|
||||
-- Για περισσότερες πληροφορίες για οποιαδήποτε συνάρτηση ή τύπο,
|
||||
-- μπορείτε να χρησιμοποιήσετε το `:i`:
|
||||
|
||||
> :i (+)
|
||||
class Num a where
|
||||
(+) :: a -> a -> a
|
||||
...
|
||||
-- Defined in ‘GHC.Num’
|
||||
infixl 6 +
|
||||
|
||||
-- Μπορείτε επίσης να τρέξετε κάθε συνάρτηση με τύπο `IO ()`
|
||||
|
||||
> sayHello
|
||||
What is your name?
|
||||
Friend!
|
||||
Hello, Friend!
|
||||
|
||||
```
|
||||
|
||||
Υπάρχουν πολλά ακόμα πράγματα να εξερευνήσετε στην Haskell, όπως τα typeclasses
|
||||
και διάφορα monads! Αυτές οι μαθηματικά ορισμένες έννοιες είναι που κάνουν την
|
||||
Haskell αυστηρή, αγνή και κομψή! Θα τελειώσουμε αυτήν την σύντομη περιήγηση με
|
||||
ένα τελευταίο παράδειγμα, η υλοποίηση της QuickSort σε Haskell:
|
||||
|
||||
```haskell
|
||||
qsort [] = []
|
||||
qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
|
||||
where lesser = filter (< p) xs
|
||||
greater = filter (>= p) xs
|
||||
```
|
||||
|
||||
Υπάρχουν 2 παραδοσιακοί τρόποι να εγκαταστήσετε την Haskell:
|
||||
- [Cabal-based installation](http://www.haskell.org/platform/),
|
||||
- [Stack-based process](https://www.stackage.org/install).
|
||||
|
||||
Στις παρακάτω πηγές μπορείτε να βρείτε αρκετά κομψές εισαγωγές στην Haskell
|
||||
- [Learn you a Haskell](http://learnyouahaskell.com/),
|
||||
- [Happy Learn Haskell Tutorial](http://www.happylearnhaskelltutorial.com/),
|
||||
- [Real World Haskell](http://book.realworldhaskell.org/)
|
Loading…
Reference in New Issue
Block a user