mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-08-31 18:32:22 +02:00
Simplify language codes in directories
This commit is contained in:
86
sv/bf.md
Normal file
86
sv/bf.md
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
language: BF
|
||||
filename: brainfuck-sv.bf
|
||||
contributors:
|
||||
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
|
||||
- ["Mathias Bynens", "http://mathiasbynens.be/"]
|
||||
translators:
|
||||
- ["Richard Lindberg", "https://github.com/Lidenburg"]
|
||||
lang: sv-se
|
||||
---
|
||||
|
||||
Brainfuck (ej versaliserat förutom vid ny mening) är ett extremt
|
||||
minimalistiskt Turing-komplett programmeringsspråk med endast 8 kommandon.
|
||||
|
||||
Du kan testa brainfuck i din webbläsare via [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/).
|
||||
|
||||
```bf
|
||||
Alla karaktärer förutom "><+-.,[]" (inte inkluderat citattecken) ignoreras.
|
||||
|
||||
Brainfuck är representerat av ett fält med 30 000 celler initialiserade till
|
||||
noll och en data pekare som pekar på den valda cellen.
|
||||
|
||||
Det finns åtta kommandon:
|
||||
+ : Ökar värdet av den valda cellen med ett.
|
||||
- : Minskar värdet av den valda cellen med ett.
|
||||
> : Flyttar data pekaren till nästa cell (cellen till höger).
|
||||
< : Flyttar data pekaren till förra cellen (cellen till vänster).
|
||||
. : Skriver ut ASCII värdet av den valda cellen (t.ex. 65 = 'A').
|
||||
, : Läser in en karaktär till den valda cellen.
|
||||
[ : Om värdet vid den valda cellen är noll, hoppa till matchande ].
|
||||
Annars fortsätts till nästa instruktion.
|
||||
] : Om värdet vid den valda cellen är noll, fortsätt till nästa instruktion.
|
||||
Annars, gå tillbaka till matchande ].
|
||||
|
||||
[ och ] formar en while loop.
|
||||
|
||||
Nedan är ett exempel på ett simpelt brainfuck program.
|
||||
|
||||
++++++ [ > ++++++++++ < - ] > +++++ .
|
||||
|
||||
Programmet skriver ut bokstaven 'A'. Först ökar den värdet av cell #1 till 6.
|
||||
Cell #1 kommer att användas för att loopa. Sen börjar den loopen (vid '[') och
|
||||
flyttar till cell #2. Den ökar värdet av cell #2 10 gånger, går tillbaka till
|
||||
cell #1 och minskar den med 1. Den gör det här 6 gånger (så många iterationer
|
||||
det tar för cell #1 att bli noll).
|
||||
|
||||
Nu är programmet på cell #1, vilket har ett värde av 0 och cell #2 har värdet 60.
|
||||
Programmet flyttar pekaren till cell #2 och ökar värdet med 5, vilket leder till
|
||||
att cell #2 har ett värde av 65 (vilket är bokstaven 'A' i ASCII), sedan skriver
|
||||
den ut cell #2 och bokstaven 'A' skrivs ut till skärmen.
|
||||
|
||||
|
||||
, [ > + < - ] > .
|
||||
|
||||
Det här programmet läser en karaktär från användaren och kopierar karaktären
|
||||
till cell #1. Sedan startas en loop. Pekaren flyttas till cell #2, värder ökas
|
||||
med ett, pekaren flyttas tillbaka till cell #1 och minskar värdet med ett.
|
||||
Det här fortsätter tills cell #1 innehåller noll och cell #2 innehåller det
|
||||
värde som cell #1 innehöll från början. Eftersom att programmet vid slutet av
|
||||
loopen är på cell #1 flyttas pekaren till cell #2 och sedan skriver den ut
|
||||
värdet av cell #2 i ASCII.
|
||||
|
||||
Värt att komma ihåg är att programmet ovan kan skrivas utan mellanslag också:
|
||||
|
||||
,[>+<-]>.
|
||||
|
||||
|
||||
Försök och lista ut vad det här programmet gör:
|
||||
|
||||
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
|
||||
|
||||
Programmet tar två nummer som indata, och multiplicerar dem.
|
||||
|
||||
Kärnan av det är att den först läser in två tal/bokstäver. Sedan startar
|
||||
den yttre loopen som beror på cell #1. Sedan går den vidare till cell #2 och
|
||||
startar den innre loopen som beror på cell #2 och ökar cell #3. Men det uppstår
|
||||
ett problem: Vid slutet av den innre loopen är cell #2 noll. Vilket betyder att
|
||||
den inre loopen inte kommer att fungera tills nästa gång. För att lösa det här
|
||||
problemet ökas också cell #4 som sedan kopieras till cell #2.
|
||||
Sedan är resultatet i cell #3.
|
||||
```
|
||||
|
||||
Och det är brainfuck. Inte så svårt va? För skojs skull kan du skriva dina egna
|
||||
brainfuck program, eller skriva en egen brainfuck interpretator i ett annat
|
||||
språk. interpretatorn är ganska simpel att implementera, men om man är en
|
||||
masochist, testa att skriva en brainfuck interpretator… i brainfuck.
|
460
sv/haskell.md
Normal file
460
sv/haskell.md
Normal file
@@ -0,0 +1,460 @@
|
||||
---
|
||||
language: Haskell
|
||||
filename: learnhaskell-sv.hs
|
||||
contributors:
|
||||
- ["Adit Bhargava", "http://adit.io"]
|
||||
translators:
|
||||
- ["Edward Tjörnhammar", "http://edwtjo.me"]
|
||||
lang: sv-se
|
||||
---
|
||||
|
||||
Haskell skapades för att vara ett praktiskt, rent, funktionellt
|
||||
programmeringsspråk. Det är känt för sin använding av monader och dess
|
||||
härledande typsystem men anledningen till att jag ständigt återbesöker språket
|
||||
är på grund av dess elegans. Haskell gör programmering till ett rent nöje.
|
||||
|
||||
```haskell
|
||||
-- Radkommenterar börjar med två bindestreck.
|
||||
{- Flerradskommentarer innesluts av vänster/höger måsvinge bindestreck
|
||||
block på detta vis.
|
||||
-}
|
||||
|
||||
----------------------------------------------------
|
||||
-- 1. Fördefinierade datatyper och operatorer
|
||||
----------------------------------------------------
|
||||
|
||||
-- Du har siffror
|
||||
3 -- 3
|
||||
|
||||
-- Matte fungerar som förväntat
|
||||
1 + 1 -- 2
|
||||
8 - 1 -- 7
|
||||
10 * 2 -- 20
|
||||
35 / 5 -- 7.0
|
||||
|
||||
-- Division är normalt inte heltalsdivision
|
||||
35 / 4 -- 8.75
|
||||
|
||||
-- Heltalsdivision, här infix div
|
||||
35 `div` 4 -- 8
|
||||
|
||||
-- Boolar (Sant och Falskt) är fördefinierade
|
||||
True
|
||||
False
|
||||
|
||||
-- Samt dess operationer
|
||||
not True -- False
|
||||
not False -- True
|
||||
1 == 1 -- True
|
||||
1 /= 1 -- False
|
||||
1 < 10 -- True
|
||||
|
||||
-- I ovanstående exempel är `not` en funktion vilken bara tar ett argument.
|
||||
-- Haskell behöver inte paranteser för sina funktionsanrop... alla argument
|
||||
-- ges mellanslagsseparerade direkt efter funktionen. Det övergripande mönstret
|
||||
-- är:
|
||||
-- func arg1 arg2 arg3...
|
||||
-- Se sektionen om funktioner för information om hur du skriver dina egna.
|
||||
|
||||
-- Strängar och bokstäver
|
||||
"Detta är en sträng"
|
||||
'a' -- bokstav
|
||||
'Du kan inte använda enkelfnutt för strängar.' -- fel!
|
||||
|
||||
-- Strängar kan konkateneras
|
||||
"Hej " ++ "världen!" -- "Hej världen!"
|
||||
|
||||
-- En sträng är en lista av bokstäver
|
||||
['H', 'e', 'j', 's', 'a', 'n'] -- "Hejsan"
|
||||
"Detta är en sträng" !! 0 -- 'D'
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
-- 2. Listor och Tupler
|
||||
----------------------------------------------------
|
||||
|
||||
-- Varje element i en lista måste ha samma typ.
|
||||
-- Dessa listor är ekvivalenta:
|
||||
[1, 2, 3, 4, 5]
|
||||
[1..5]
|
||||
|
||||
-- Intervall är mångsidiga.
|
||||
['A'..'F'] -- "ABCDEF"
|
||||
|
||||
-- Man kan stega intervall.
|
||||
[0,2..10] -- [0, 2, 4, 6, 8, 10]
|
||||
[5..1] -- [] (Haskell förutsätter normalt inkrement)
|
||||
[5,4..1] -- [5, 4, 3, 2, 1]
|
||||
|
||||
-- Indexering in i en lista
|
||||
[1..10] !! 3 -- 4 (nollindexerat)
|
||||
|
||||
-- Man kan ha oändliga listor i Haskell!
|
||||
[1..] -- listan över alla naturliga tal
|
||||
|
||||
-- Oändliga listor fungerar enbart för att Haskell har "lat evaluering".
|
||||
-- Det betyder att Haskell bara evaluerar de uttryck den måste. Du kan alltså
|
||||
-- fråga efter det 1000:e elementet i en oändlig lista och Haskell kommer då ge
|
||||
-- dig det:
|
||||
|
||||
[1..] !! 999 -- 1000
|
||||
|
||||
-- Nu har Haskell evaluerat element 1 till 1000 i denna lista... men resten
|
||||
-- av medlemmarna i denna oändliga lista existerar inte ännu! Haskell kommer
|
||||
-- faktiskt inte utvärdera element den inte måste.
|
||||
|
||||
-- Sammanslagning av två listor
|
||||
[1..5] ++ [6..10]
|
||||
|
||||
-- Lägg till 0 vid listhuvudet
|
||||
0:[1..5] -- [0, 1, 2, 3, 4, 5]
|
||||
|
||||
-- fler listoperationer som huvud, svans, initiella samt sista
|
||||
head [1..5] -- 1
|
||||
tail [1..5] -- [2, 3, 4, 5]
|
||||
init [1..5] -- [1, 2, 3, 4]
|
||||
last [1..5] -- 5
|
||||
|
||||
-- listomfattningar
|
||||
[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
|
||||
|
||||
-- med bivilkor
|
||||
[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
|
||||
|
||||
-- Varje element i en tupel kan ha olika typ men en tupel kan bara ha en
|
||||
-- fixerad, eller statisk, längd.
|
||||
-- En tupel:
|
||||
("haskell", 1)
|
||||
|
||||
-- För att komma åt element i ett par, alltså en 2-tupel, finns
|
||||
-- de fördefinierade funktionerna:
|
||||
fst ("haskell", 1) -- "haskell"
|
||||
snd ("haskell", 1) -- 1
|
||||
|
||||
----------------------------------------------------
|
||||
-- 3. Funktioner
|
||||
----------------------------------------------------
|
||||
-- En enkel funktion med två parametrar
|
||||
add a b = a + b
|
||||
|
||||
-- Notera även att om du använder ghci (Haskellinterpretatorn) kommer du behöva
|
||||
-- använda `let` namnbindning för att synliggöra din funktionsdeklaration,
|
||||
-- alltså
|
||||
let add a b = a + b
|
||||
|
||||
-- För att använda funktionen
|
||||
add 1 2 -- 3
|
||||
|
||||
-- Man kan även göra funktionsanropet infix, alltså mellan parametersättningen,
|
||||
-- med hjälp av bakåtfnuttar:
|
||||
1 `add` 2 -- 3
|
||||
|
||||
-- Du kan även definiera funktioner vars funktionsnamn avsaknar bokstäver!
|
||||
-- Med hjälp av parenteser kan du därmed definiera operatorer (normalt infix)!
|
||||
-- Följande är en operator för heltalsdivision, vilken förlitar sig på div:
|
||||
(//) a b = a `div` b
|
||||
35 // 4 -- 8
|
||||
|
||||
-- Funktionsvakter: ett enkelt sätt att grena ut dina funktioner
|
||||
fib x
|
||||
| x < 2 = 1
|
||||
| otherwise = fib (x - 1) + fib (x - 2)
|
||||
|
||||
-- Mönstermatchning fungerar på liknande vis. Här ger vi tre olika
|
||||
-- parametermatchningar för vårat fib-resulat. Haskell kommer automatiskt följa
|
||||
-- första bästa träff, uppifrån ned, vars vänstra sida om likhetstecknet matchar
|
||||
-- anroparens parametervärde.
|
||||
fib 1 = 1
|
||||
fib 2 = 2
|
||||
fib x = fib (x - 1) + fib (x - 2)
|
||||
|
||||
-- Mönstermatchning på tupler:
|
||||
foo (x, y) = (x + 1, y + 2)
|
||||
|
||||
-- Mönstermatchning på listor. Här är `x` det första elementet i listan och `xs`
|
||||
-- är resten av listan. Nu kan vi skriva våran egen map-funktion
|
||||
minMap func [] = []
|
||||
minMap func (x:xs) = func x:(minMap func xs)
|
||||
|
||||
-- Anonyma funktioner, eller lambdauttryck, skapas med hjälp av omvänt
|
||||
-- snedstreck, följt av parametrarna
|
||||
minMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
|
||||
|
||||
-- Användning av fold (även kallad `inject`, `reduce`, osv.) tillsammans med en
|
||||
-- anonym funktion. `fold1` är en vänstervikande funktion och använder första
|
||||
-- värdet i listan som det initiella värdet för ackumulatorn.
|
||||
foldl1 (\acc x -> acc + x) [1..5] -- 15
|
||||
|
||||
----------------------------------------------------
|
||||
-- 4. Mer funktioner
|
||||
----------------------------------------------------
|
||||
|
||||
-- Partiell applikation:
|
||||
-- Om du inte anropar funktionen med alla sina argument
|
||||
-- blir den partiellt applicerad. Det betyder att du erhåller en funktion där en
|
||||
-- delmängd av parametrarna blivit värdesatta men några är fortfarande fria.
|
||||
add a b = a + b
|
||||
foo = add 10 -- foo är nu en funktion som tar ett nummer och lägger till 10 till
|
||||
-- det
|
||||
foo 5 -- 15
|
||||
|
||||
-- Ett annat sätt att skriva samma sak
|
||||
foo = (10+)
|
||||
foo 5 -- 15
|
||||
|
||||
-- Funktionskomposition:
|
||||
-- Operatorn `.` kedjar ihop funktioner
|
||||
-- Till exempel, nedan är `foo` en funktion som tar ett värde, den adderar 10
|
||||
-- till det, multiplicerar det resultatet med 4 och sen ersätts med det värdet.
|
||||
foo = (4*) . (10+)
|
||||
|
||||
-- 4*(10+5) = 60
|
||||
foo 5 -- 60
|
||||
|
||||
-- Precedensordning:
|
||||
-- Haskell har en operator `$`. Denna operator applicerar en funktion till en
|
||||
-- given parameter med dess precedens. I kontrast mot vanlig
|
||||
-- funktionsapplikation, vilket har den högsta utvärderingsprioriteten 10 och
|
||||
-- associerar till vänster, har denna prioritetsordning 0 och är
|
||||
-- högerassociativ. Denna låga prioritet medför att parameteruttrycket till
|
||||
-- höger om operatorn får det reducerat innan det appliceras till sin vänster.
|
||||
|
||||
-- före
|
||||
even (fib 7) -- falskt
|
||||
|
||||
-- ekvivalent
|
||||
even $ fib 7 -- falskt
|
||||
|
||||
-- med funktionskomposition
|
||||
even . fib $ 7 -- falskt
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
-- 5. Typsignaturer
|
||||
----------------------------------------------------
|
||||
|
||||
-- Haskell har ett väldigt starkt typsystem, alla giltiga uttryck har en typ.
|
||||
|
||||
-- Några grundläggande typer:
|
||||
5 :: Integer
|
||||
"hello" :: String
|
||||
True :: Bool
|
||||
|
||||
-- Funktioner har också typer,
|
||||
-- `not` tar en bool och returnerar en bool:
|
||||
-- not :: Bool -> Bool
|
||||
|
||||
-- Här är ett exempel på en funktionssignatur vilken beskriver en funktion som
|
||||
-- reducerar två heltal till ett:
|
||||
-- add :: Integer -> Integer -> Integer
|
||||
|
||||
-- Trots att Haskell härleder typen på icke typsatta uttryck är det bra form att
|
||||
-- explicit ange dessa för ens deklarerade funktioner:
|
||||
double :: Integer -> Integer
|
||||
double x = x * 2
|
||||
|
||||
----------------------------------------------------
|
||||
-- 6. Kontrollflöde och Ifsatser
|
||||
----------------------------------------------------
|
||||
|
||||
-- if-sats
|
||||
haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
|
||||
|
||||
-- if-statser kan spridas över rader men indentering har betydelse
|
||||
haskell = if 1 == 1
|
||||
then "awesome"
|
||||
else "awful"
|
||||
|
||||
-- case uttryck: följande är ett exempel på kommandoradsparsning
|
||||
case args of
|
||||
"help" -> printHelp
|
||||
"start" -> startProgram
|
||||
_ -> putStrLn "bad args"
|
||||
|
||||
-- Haskell har inte loopar istället används recursion.
|
||||
-- map applicerar en funktion över varje element i en lista
|
||||
|
||||
map (*2) [1..5] -- [2, 4, 6, 8, 10]
|
||||
|
||||
-- man kan deklarera en for funktion genom att använda map
|
||||
for array func = map func array
|
||||
|
||||
-- och därefter använda den tillsammans med en anonym funktion för att
|
||||
-- efterlikna en loop
|
||||
for [0..5] $ \i -> show i
|
||||
|
||||
-- men vi kunde även ha skrivit på följande vis:
|
||||
for [0..5] show
|
||||
|
||||
-- Du kan använda foldl eller foldr för att reducera en lista
|
||||
-- foldl <fn> <initial value> <list>
|
||||
foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
|
||||
|
||||
-- Vilket är samma sak som
|
||||
(2 * (2 * (2 * 4 + 1) + 2) + 3)
|
||||
|
||||
-- foldl viker från vänster, foldr från höger
|
||||
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
|
||||
|
||||
-- Vilket alltså är samma sak som
|
||||
(2 * 1 + (2 * 2 + (2 * 3 + 4)))
|
||||
|
||||
----------------------------------------------------
|
||||
-- 7. Datatyper
|
||||
----------------------------------------------------
|
||||
|
||||
-- Såhär definierar du din egen datatyp i Haskell
|
||||
data Color = Red | Blue | Green
|
||||
|
||||
-- När du gjort det kan du använda den i funktionssignaturer och uttryck
|
||||
say :: Color -> String
|
||||
say Red = "Du är Rö!"
|
||||
say Blue = "Du är Blå!"
|
||||
say Green = "Du är Grön!"
|
||||
|
||||
-- Dina datatyper kan även ta parametrar
|
||||
data Maybe a = Nothing | Just a
|
||||
|
||||
-- Följande uttryck är alla specialiseringar av typen Maybe
|
||||
Just "hello" -- har typen `Maybe String`
|
||||
Just 1 -- har typen `Maybe Int`
|
||||
Nothing -- har typen `Maybe a` för alla `a`
|
||||
|
||||
----------------------------------------------------
|
||||
-- 8. Haskell IO
|
||||
----------------------------------------------------
|
||||
|
||||
-- Även om IO inte kan förstås fullt ut utan att först förklara monader är det
|
||||
-- inte svårt att lära sig tillräckligt för att komma igång
|
||||
|
||||
-- När ett Haskellprogram körs är det topnivåns main som körs. Main måste
|
||||
-- returnerna ett värde av typen `IO a`, för någon typ `a`. Till exempel:
|
||||
|
||||
main :: IO ()
|
||||
main = putStrLn $ "Hej, himmelen! " ++ (say Blue)
|
||||
-- putStrLn har typen type String -> IO ()
|
||||
|
||||
-- Det är enkelt att göra IO om du kan implementera ditt program som en funktion
|
||||
-- från String till String. Funktionen
|
||||
-- interact :: (String -> String) -> IO ()
|
||||
-- tar denna funktion och matar den med strängdata från stdin och skriver ut
|
||||
-- resultatet som en sträng på stdout
|
||||
|
||||
countLines :: String -> String
|
||||
countLines = show . length . lines
|
||||
|
||||
main' = interact countLines
|
||||
|
||||
-- Du kan tänka på värden av typen `IO ()` som att representera
|
||||
-- händelsesekvenser du vill att din dator skall utföra, likt imperativa språk.
|
||||
-- För att kedja ihop händelsesekvenser använder man ett syntaktiskt socker
|
||||
-- kallat do-notation. Som exempel:
|
||||
|
||||
sägHej :: IO ()
|
||||
sägHej = do
|
||||
putStrLn "Vad heter du?"
|
||||
namn <- getLine -- denna raden läser en rad från stdin och vi binder den till
|
||||
-- funktionsnamnet `namn`
|
||||
putStrLn $ "Hejsan, " ++ namn
|
||||
|
||||
-- Övning: Skriv din egen version av interageringsfunktionen `interact` som bara
|
||||
-- läser en rad från stdin, vanliga `interact` läser till EOF.
|
||||
|
||||
-- Koden i sägHej kommer dock aldrig exekveras. Den enda handlingen som blir det
|
||||
-- är som bekant utvärderingen av `main`.
|
||||
-- För att köra `sägHej` kommentera ut definition av `main` ovan och
|
||||
-- avkommentera nedanstående version:
|
||||
-- main = sayHello
|
||||
|
||||
-- Låt oss bättre förstå hur funktionen `getLine` vi just använde fungerar. Dess
|
||||
-- typsignatur är:
|
||||
-- getLine :: IO String
|
||||
-- Du kan tänka på typen `IO a` som att representeras av ett datorprogram vilken
|
||||
-- kommer generera ett värde av typen `a` när det exekveras (utöver allt annat
|
||||
-- det kan tänkas göra). Vi kan därtill binda detta värde till ett namn för
|
||||
-- återanvändning genom att använda `<-`. Vi kan även skapa våran egen handling
|
||||
-- av typen `IO String`:
|
||||
|
||||
handling :: IO String
|
||||
handling = do
|
||||
putStrLn "Detta är en rad, tihi"
|
||||
input1 <- getLine
|
||||
input2 <- getLine
|
||||
-- Typen av hela `do` blocket är vad som står på sista raden. Här är även
|
||||
-- `return` inte ett nyckelord i språket utan en funktion med en typsignatur
|
||||
return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
|
||||
|
||||
-- Vi kan använda `return` på samma sätt som vi använde `getLine`:
|
||||
|
||||
main'' = do
|
||||
putStrLn "Jag kommer eka två rader!"
|
||||
result <- handling
|
||||
putStrLn result
|
||||
putStrLn "Tack och hej leverpastej!"
|
||||
|
||||
-- Typen `IO` är ett exempel på en monad. Sättet Haskell utnyttjar monader på är
|
||||
-- anledningen till hur språket kan bibehålla sin renhet. En funktion vilken
|
||||
-- interagerar med omvärlden (alltså gör IO) blir markerad med `IO` i sin
|
||||
-- typsignatur. Detta låter oss enkelt upptäcka vilka funktioner som är "rena"
|
||||
-- (inte interagerar med omvärlden eller är tillståndsoberoende) and vilka
|
||||
-- funktioner som inte är det.
|
||||
|
||||
-- Detta är ett mäktigt särdrag eftersom det är enkelt att köra rena funktioner
|
||||
-- sammanlöpande; Samtidig programmering är enkel att göra i Haskell.
|
||||
|
||||
----------------------------------------------------
|
||||
-- 9. Haskell REPL (kodtolk)
|
||||
----------------------------------------------------
|
||||
|
||||
-- Efter installation av GHC kan vi starta tolken genom att skriva `ghci`.
|
||||
-- Nu kan du mata in Haskellkod direkt i den. Nya värden måste introduceras med
|
||||
-- `let` bindning:
|
||||
|
||||
let foo = 5
|
||||
|
||||
-- Du kan även se typen av namnbindningen med `:t`
|
||||
|
||||
> :t foo
|
||||
foo :: Integer
|
||||
|
||||
-- Operatorer, som `+`, `:` och `$` är funktioner. Deras typ kan inspekteras
|
||||
-- genom att skriva operatorn mellan parenteser:
|
||||
|
||||
> :t (:)
|
||||
(:) :: a -> [a] -> [a]
|
||||
|
||||
-- Du kan få ytterliggare information om något namn genom att använda `:i`
|
||||
|
||||
> :i (+)
|
||||
class Num a where
|
||||
(+) :: a -> a -> a
|
||||
...
|
||||
-- Defined in ‘GHC.Num’
|
||||
infixl 6 +
|
||||
|
||||
-- Du kan även köra alla handlingar av typen `IO ()` direkt i tolken
|
||||
|
||||
> sägHej
|
||||
Vad är ditt namn?
|
||||
Kompis!
|
||||
Hello, Kompis!
|
||||
```
|
||||
|
||||
Det finns mycket mer att upptäcka med Haskell, inklusive typklasser och monader.
|
||||
Vilka är de stora idéerna som gör Haskell till det roliga programmeringsspråket
|
||||
det är. Jag lämar dig med ett sista exempel; En implementation av quicksort:
|
||||
|
||||
```haskell
|
||||
qsort [] = []
|
||||
qsort (p:xs) = qsort mindre ++ [p] ++ qsort större
|
||||
where mindre = filter (< p) xs
|
||||
större = filter (>= p) xs
|
||||
```
|
||||
|
||||
Det finns två populära sätt att installera Haskell på: Den traditionella [Cabal sättet](http://www.haskell.org/platform/), eller det nyare [Stack sättet](https://www.stackage.org/install).
|
||||
|
||||
Du kan finna vänligare och/eller djupare introduktioner till Haskell på engelska
|
||||
från:
|
||||
[Learn you a Haskell](http://learnyouahaskell.com/),
|
||||
[Happy Learn Haskell Tutorial](http://www.happylearnhaskelltutorial.com/) eller
|
||||
[Real World Haskell](http://book.realworldhaskell.org/).
|
84
sv/json.md
Normal file
84
sv/json.md
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
language: JSON
|
||||
filename: learnjson-sv.json
|
||||
contributors:
|
||||
- ["Anna Harren", "https://github.com/iirelu"]
|
||||
- ["Marco Scannadinari", "https://github.com/marcoms"]
|
||||
- ["himanshu", "https://github.com/himanshu81494"]
|
||||
- ["Michael Neth", "https://github.com/infernocloud"]
|
||||
translators:
|
||||
- ["Lari Kovanen", "https://github.com/larkov"]
|
||||
- ["Joakim Lahtinen", "https://github.com/VibyJocke"]
|
||||
lang: sv-se
|
||||
---
|
||||
|
||||
JSON är ett extremt enkelt datautbytesformat. Som [json.org](http://json.org) beskriver så är det lätt för människor att läsa och skriva, och för datorer att tolka och generera.
|
||||
|
||||
En bit av JSON måste representera antingen:
|
||||
* En samling av namn/värde-par (`{ }`). I olika språk kan denna realiseras som ett objekt, struct, dictionary, hash-tabell, nyckellista eller en associativ array.
|
||||
* En ordnad lista av värden (`[ ]`). I olika språk kan denna realiseras som en array, vektor, lista eller sekvens.
|
||||
|
||||
JSON i dess renaste form har inga kommentarer, men de flesta tolkarna accepterar C-stils (`//`, `/* */`) kommentarer. Vissa tolkar tolererar även komman efter sista elementet i en array, eller det sista attributet av ett objekt, men dessa bör undvikas för bättre kompabilitet.
|
||||
|
||||
Detta dokument kommer dock att tillämpa 100% giltigt JSON. Lyckligtvis så är resten av dokumentet självförklarande.
|
||||
|
||||
Följande datatyper stöds:
|
||||
* Strängar: `"hello"`, `"\"A quote.\""`, `"\u0abe"`, `"Newline.\n"`
|
||||
* Nummer: `23`, `0.11`, `12e10`, `3.141e-10`, `1.23e+4`
|
||||
* Objekt: `{ "key": "value" }`
|
||||
* Arrayer: `["Values"]`
|
||||
* Övriga: `true`, `false`, `null`
|
||||
|
||||
```json
|
||||
{
|
||||
"nyckel": "värde",
|
||||
|
||||
"nycklar": "måste alltid omslutas med dubbla citationstecken",
|
||||
"nummer": 0,
|
||||
"strängar": "Alla unicode-tecken (inklusive \"escaping\") är tillåtna.",
|
||||
"boolska värden?": true,
|
||||
"nullvärden": null,
|
||||
|
||||
"stora tal": 1.2e+100,
|
||||
|
||||
"objekt": {
|
||||
"kommentar": "De flesta datastukturerna i JSON kommer i form av objekt.",
|
||||
|
||||
"matris": [0, 1, 2, 3, "Matriser kan innehålla vad som helst.", 5],
|
||||
|
||||
"ytterligare objekt": {
|
||||
"kommentar": "Objekten kan vara nästlade."
|
||||
}
|
||||
},
|
||||
|
||||
"trams": [
|
||||
{
|
||||
"kaliumkällor": ["bananer"]
|
||||
},
|
||||
[
|
||||
[1, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 1, "neo"],
|
||||
[0, 0, 0, 1]
|
||||
]
|
||||
],
|
||||
|
||||
"alternativ formatering": {
|
||||
"kommentar": "kolla på detta!"
|
||||
, "kommats position": "spelar ingen roll - så länge det kommer innan värdet"
|
||||
, "en kommentar till": "vad fint"
|
||||
},
|
||||
|
||||
|
||||
|
||||
"blanksteg": "Spelar ingen roll.",
|
||||
|
||||
|
||||
|
||||
"det var kort": "Nu är du klar och kan allt vad JSON har att erbjuda."
|
||||
}
|
||||
```
|
||||
|
||||
## Fortsatt läsning
|
||||
|
||||
* [JSON.org](http://json.org/json-sv.html) Allt du kan tänkas vilja veta om JSON, och lite därtill.
|
365
sv/nix.md
Normal file
365
sv/nix.md
Normal file
@@ -0,0 +1,365 @@
|
||||
---
|
||||
language: Nix
|
||||
filename: learn-sv.nix
|
||||
contributors:
|
||||
- ["Chris Martin", "http://chris-martin.org/"]
|
||||
translators:
|
||||
- ["Edward Tjörnhammar", "http://edwtjo.me"]
|
||||
lang: sv-se
|
||||
---
|
||||
|
||||
Nix är ett enkelt funktionelt språk utvecklat för
|
||||
[Nix pakethanteraren](https://nixos.org/nix/) och
|
||||
[NixOS](https://nixos.org/) linuxdistributionen.
|
||||
|
||||
Du kan utvärdera Nix uttryck genom att använda
|
||||
[nix-instantiate](https://nixos.org/nix/manual/#sec-nix-instantiate)
|
||||
eller [`nix-repl`](https://github.com/edolstra/nix-repl).
|
||||
|
||||
```nix
|
||||
with builtins; [
|
||||
|
||||
# Kommentarer
|
||||
#=========================================
|
||||
|
||||
# Inlinekommentarer ser ut såhär.
|
||||
|
||||
/* Flerradskommentarer ser ut
|
||||
såhär. */
|
||||
|
||||
|
||||
# Booleaner
|
||||
#=========================================
|
||||
|
||||
(true && false) # Och
|
||||
#=> false
|
||||
|
||||
(true || false) # Eller
|
||||
#=> true
|
||||
|
||||
(if 3 < 4 then "a" else "b") # Villkorlig
|
||||
#=> "a"
|
||||
|
||||
|
||||
# Heltal
|
||||
#=========================================
|
||||
|
||||
# Heltal är den enda numeriska typen.
|
||||
|
||||
1 0 42 (-3) # Några heltal
|
||||
|
||||
(4 + 6 + 12 - 2) # Addition
|
||||
#=> 20
|
||||
|
||||
(7 / 2) # Division
|
||||
#=> 3
|
||||
|
||||
|
||||
# Strängar
|
||||
#=========================================
|
||||
|
||||
"Stränglitteraler omgärdas av raka citationstecken."
|
||||
|
||||
"
|
||||
Stränglitteraler kan sträcka sig
|
||||
över flera rader.
|
||||
"
|
||||
|
||||
''
|
||||
Detta kallas för en indenterad strängliteral, omgärdad av dubbla apostrofer
|
||||
Den plockar intelligent bort ledande blanktecken.
|
||||
''
|
||||
|
||||
''
|
||||
a
|
||||
b
|
||||
''
|
||||
#=> "a\n b"
|
||||
|
||||
("ab" + "cd") # Strängkonkatenering
|
||||
#=> "abcd"
|
||||
|
||||
# Antikvotering låter dig bädda in språkvärden i strängar.
|
||||
("Din hemkatalog är ${getEnv "HOME"}")
|
||||
#=> "Din hemkatalog är /home/alice"
|
||||
|
||||
|
||||
# Sökvägar
|
||||
#=========================================
|
||||
|
||||
# Nix har en primitiv, inbyggd, typ för sökvägar.
|
||||
/tmp/tutorials/learn.nix
|
||||
|
||||
# Relativa sökvägar förenas med sökvägen till dess definerande fils sökväg
|
||||
# vid tolkningstillfället för att skapa dess absoluta sökväg.
|
||||
|
||||
tutorials/learn.nix
|
||||
#=> /the-base-path/tutorials/learn.nix
|
||||
|
||||
# En sökväg måste innehålla åtminstonde ett snedstreck, så en relativ sökväg
|
||||
# till en fil i samma katalog måste ges ett "./" prefix
|
||||
|
||||
./learn.nix
|
||||
#=> /the-base-path/learn.nix
|
||||
|
||||
# Divisionsoperatorn / måste omges av blanksteg om man vill att det skall
|
||||
# tolkas som heltalsdivision
|
||||
|
||||
7/2 # Detta är en sökväg
|
||||
(7 / 2) # Detta är heltalsdivision
|
||||
|
||||
|
||||
# Importer
|
||||
#=========================================
|
||||
|
||||
# En nix fil innehåller ett enstaka topnivåuttryck utan fria variabler.
|
||||
# Ett importuttryck evalueras till värdet på filen som den importerar.
|
||||
(import /tmp/foo.nix)
|
||||
|
||||
# Importer kan också specificeras med hjälp av strängar.
|
||||
(import "/tmp/foo.nix")
|
||||
|
||||
# Importsökvägar måste vara absoluta. Sökvägslitteraler härleds vid
|
||||
# tolkningstillfället så följande är ok.
|
||||
(import ./foo.nix)
|
||||
|
||||
# Men detta är inte något som sker med strängar.
|
||||
(import "./foo.nix")
|
||||
#=> error: string ‘foo.nix’ doesn't represent an absolute path
|
||||
|
||||
|
||||
# Let
|
||||
#=========================================
|
||||
|
||||
# `let` block tillåter oss att binda värden till namn.
|
||||
(let x = "a"; in
|
||||
x + x + x)
|
||||
#=> "aaa"
|
||||
|
||||
# Bindingar kan referera till varandra och deras ordning sinsemellan spelar
|
||||
# ingen roll.
|
||||
(let y = x + "b";
|
||||
x = "a"; in
|
||||
y + "c")
|
||||
#=> "abc"
|
||||
|
||||
# Innre bindningar skuggar utanpåliggande bindingar.
|
||||
(let a = 1; in
|
||||
let a = 2; in
|
||||
a)
|
||||
#=> 2
|
||||
|
||||
|
||||
# Funktioner
|
||||
#=========================================
|
||||
|
||||
(n: n + 1) # En lambdafunktion som lägger till 1
|
||||
|
||||
((n: n + 1) 5) # Samma funktion applicerad på 5
|
||||
#=> 6
|
||||
|
||||
# Det finns ingen syntax för direkt namngivna funktioner, istället binder man
|
||||
# dessa med `let` block som andra värden.
|
||||
(let succ = (n: n + 1); in succ 5)
|
||||
#=> 6
|
||||
|
||||
# En funktion är en lambda med en parameter. Flera parameterar kan ges med
|
||||
# hjälp av currying.
|
||||
((x: y: x + "-" + y) "a" "b")
|
||||
#=> "a-b"
|
||||
|
||||
# Vi kan också ha namngivna funktionsparametrar, vilket vi kommer komma till
|
||||
# senare, efter att vi introducerat attributset.
|
||||
|
||||
# Listor
|
||||
#=========================================
|
||||
|
||||
# Listor noteras med hakparenteser.
|
||||
|
||||
(length [1 2 3 "x"])
|
||||
#=> 4
|
||||
|
||||
([1 2 3] ++ [4 5])
|
||||
#=> [1 2 3 4 5]
|
||||
|
||||
(concatLists [[1 2] [3 4] [5]])
|
||||
#=> [1 2 3 4 5]
|
||||
|
||||
(head [1 2 3])
|
||||
#=> 1
|
||||
(tail [1 2 3])
|
||||
#=> [2 3]
|
||||
|
||||
(elemAt ["a" "b" "c" "d"] 2)
|
||||
#=> "c"
|
||||
|
||||
(elem 2 [1 2 3])
|
||||
#=> true
|
||||
(elem 5 [1 2 3])
|
||||
#=> false
|
||||
|
||||
(filter (n: n < 3) [1 2 3 4])
|
||||
#=> [ 1 2 ]
|
||||
|
||||
|
||||
# Mängder
|
||||
#=========================================
|
||||
|
||||
# Ett attributset är en oordnad mappning av strängnycklar och värden.
|
||||
{ foo = [1 2]; bar = "x"; }
|
||||
|
||||
# Punktoperatorn . väljer ett värde från attributset:et
|
||||
{ a = 1; b = 2; }.a
|
||||
#=> 1
|
||||
|
||||
# Frågeoperatorn ? testar om en nyckel är närvarande i ett attributset
|
||||
({ a = 1; b = 2; } ? a)
|
||||
#=> true
|
||||
({ a = 1; b = 2; } ? c)
|
||||
#=> false
|
||||
|
||||
# Snedstrecksoperatorn // slår ihop två attributset:ar.
|
||||
({ a = 1; } // { b = 2; })
|
||||
#=> { a = 1; b = 2; }
|
||||
|
||||
# Värden på höger skriver över värden till vänster.
|
||||
({ a = 1; b = 2; } // { a = 3; c = 4; })
|
||||
#=> { a = 3; b = 2; c = 4; }
|
||||
|
||||
# Recursionsnyckelordet rec noterar ett rekursivt attributset (en fixpunkt)
|
||||
# i vilket attributen kan referera till varandra.
|
||||
(let a = 1; in { a = 2; b = a; }.b)
|
||||
#=> 1
|
||||
(let a = 1; in rec { a = 2; b = a; }.b)
|
||||
#=> 2
|
||||
|
||||
# Nästlade attributset:ar kan definieras bit för bit.
|
||||
{
|
||||
a.b = 1;
|
||||
a.c.d = 2;
|
||||
a.c.e = 3;
|
||||
}.a.c
|
||||
#=> { d = 2; e = 3; }
|
||||
|
||||
# Ett attributsets barn kan inte tilldelas på detta vis om attributsetet
|
||||
# självt blivit direkt tilldelat.
|
||||
{
|
||||
a = { b = 1; };
|
||||
a.c = 2;
|
||||
}
|
||||
#=> error: attribute ‘a’ already defined
|
||||
|
||||
|
||||
# Bindningsintroduktion, `with`
|
||||
#=========================================
|
||||
|
||||
# Det attributset vilket återfinns i ett `with` uttryck kommer få sina
|
||||
# värdebindningar introducerade i efterkommande uttryck.
|
||||
(with { a = 1; b = 2; };
|
||||
a + b)
|
||||
# => 3
|
||||
|
||||
# Innre bindningar skuggar yttre bindningar.
|
||||
(with { a = 1; b = 2; };
|
||||
(with { a = 5; };
|
||||
a + b))
|
||||
#=> 7
|
||||
|
||||
# Första raden av detta exempel börjar med "with builtins;" eftersom builtins
|
||||
# är ett attributset innehållande alla inbyggda hjälpfunktioner såsom
|
||||
# (length, head, tail, filter, etc.). Detta sparar oss från att hela tiden
|
||||
# referera in i det attributset:et , alltså du kan använda bara "length"
|
||||
# istället för "builtins.length".
|
||||
|
||||
|
||||
# Attributsetmönster
|
||||
#=========================================
|
||||
|
||||
# Attributset är användbara när vi skall skicka med flera värden till en
|
||||
# funktion.
|
||||
(args: args.x + "-" + args.y) { x = "a"; y = "b"; }
|
||||
#=> "a-b"
|
||||
|
||||
# Man kan använda attributsetmönster för ökad tydlighet.
|
||||
({x, y}: x + "-" + y) { x = "a"; y = "b"; }
|
||||
#=> "a-b"
|
||||
|
||||
# Attributmönster misslyckas dock om det medskickade attributmönstret
|
||||
# innehåller extra nycklar.
|
||||
({x, y}: x + "-" + y) { x = "a"; y = "b"; z = "c"; }
|
||||
#=> error: anonymous function called with unexpected argument ‘z’
|
||||
|
||||
# Genom att lägga till ", ..." kan vi ignorera ytterliggare nycklar.
|
||||
({x, y, ...}: x + "-" + y) { x = "a"; y = "b"; z = "c"; }
|
||||
#=> "a-b"
|
||||
|
||||
|
||||
# Felmeddelanden
|
||||
#=========================================
|
||||
|
||||
# `throw` gör att programtolken gör abort med dess tillhörande felmeddelande
|
||||
causes evaluation to abort with an error message.
|
||||
(2 + (throw "foo"))
|
||||
#=> error: foo
|
||||
|
||||
# `tryEval` fångar kastade fel `throw`.
|
||||
(tryEval 42)
|
||||
#=> { success = true; value = 42; }
|
||||
(tryEval (2 + (throw "foo")))
|
||||
#=> { success = false; value = false; }
|
||||
|
||||
# `abort` fungerar som `throw`, men är kritiskt och kan inte fångas.
|
||||
(tryEval (abort "foo"))
|
||||
#=> error: evaluation aborted with the following error message: ‘foo’
|
||||
|
||||
# `assert` utvärderas till det givna värdet om dess predikat är sant.
|
||||
# annars skickar den ett fångbart fel.
|
||||
(assert 1 < 2; 42)
|
||||
#=> 42
|
||||
(assert 1 > 2; 42)
|
||||
#=> error: assertion failed at (string):1:1
|
||||
(tryEval (assert 1 > 2; 42))
|
||||
#=> { success = false; value = false; }
|
||||
|
||||
|
||||
# Orenhet
|
||||
#=========================================
|
||||
|
||||
# Eftersom repeterbarhet för byggen är en kritisk egenskap för
|
||||
# Nix-pakethanteraren betonas funktionell renhet i Nix-programmeringsspråket.
|
||||
# Men med det sagt existerar det källor till orenhet
|
||||
|
||||
# Man kan referera till miljövariabler.
|
||||
(getEnv "HOME")
|
||||
#=> "/home/alice"
|
||||
|
||||
# `trace` funktionen används för att debugga. Den skriver ut första argumentet
|
||||
# till stderr och reduceras samtidigt till det andra argumentet.
|
||||
(trace 1 2)
|
||||
#=> trace: 1
|
||||
#=> 2
|
||||
|
||||
# Man kan skriva filer till Nix-store, lagringsplatsen för alla Nix-uttryck.
|
||||
# Även om detta är orent beteende är det hyfsat säkert eftersom filens
|
||||
# lagringsplats är härledd från dess innehåll och beroenden. Man kan läsa
|
||||
# filer från precis överallt. I nedanstående exempel skriver vi en fil till
|
||||
# Nix-store och sedan läser tillbaka den.
|
||||
|
||||
(let filename = toFile "foo.txt" "hello!"; in
|
||||
[filename (builtins.readFile filename)])
|
||||
#=> [ "/nix/store/ayh05aay2anx135prqp0cy34h891247x-foo.txt" "hello!" ]
|
||||
|
||||
# Vi kan också ladda ned filer till Nix-store.
|
||||
(fetchurl "https://example.com/package-1.2.3.tgz")
|
||||
#=> "/nix/store/2drvlh8r57f19s9il42zg89rdr33m2rm-package-1.2.3.tgz"
|
||||
|
||||
]
|
||||
```
|
||||
|
||||
### Vidare Läsning (eng)
|
||||
|
||||
* [Nix Manual - Nix expression language](https://nixos.org/nix/manual/#ch-expression-language)
|
||||
* [James Fisher - Nix by example - Part 1: The Nix expression language](https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55)
|
||||
* [Susan Potter - Nix Cookbook - Nix By Example](https://ops.functionalalgebra.com/nix-by-example/)
|
||||
* [Zero to Nix - Nix Tutorial](https://zero-to-nix.com/)
|
||||
* [Rommel Martinez - A Gentle Introduction to the Nix Family](https://web.archive.org/web/20210121042658/https://ebzzry.io/en/nix/#nix)
|
Reference in New Issue
Block a user