Paluu Haskelliin, osa 1
Kävin muutama vuosi sitten Haskell-ohjelmointikurssin, jota pidin todella mielenkiintoisena, mutta kielen käyttö jäi sikseen – käytön jatkamiselle ei löytynyt syitä. Haluan nyt tehdä asiaan muutoksen. Suunnitelmani on rakentaa šakkiohjelma, ei maailmanluokan sellainen mutta kuitenkin täysin toimiva, kaikilla säännöillä ja riittävän vahvana, jotta se osaisi minut päihittää. (Olen shakin suhteen amatööri.)
Käymäni kurssin materiaali suositteli Haskell Tool Stack -työkalua, ja aion sitä käyttää nytkin. Ehdotettu asennustapa *nix-järjestelmille, jossa ohjeiden mukaan haetaan skripti curl
illa ja putkitetaan sh
:lle, vaikuttaa hieman riskikkäältä mutta lukaistuni läpi 805-rivisen skriptin ajan sen.
curl -sSL https://get.haskellstack.org/ | sh
Testaan asennuksen pikaisesti komentorivitulkilla, ajamalla stack ghci
ja alla olevilla syötteillä. GHC on aika iso, parisataa megatavua.
Prelude> luku = 30 Prelude> luku 30 Prelude> successor = \n -> n + 1 Prelude> successor luku 31 Prelude> successor successor luku <interactive>:5:1: error: • Non type-variable argument in the constraint: Num (a -> a) (Use FlexibleContexts to permit this) • When checking the inferred type it :: forall a. (Num a, Num (a -> a)) => a Prelude> successor $ successor luku 32
Stackin dokumentaatio ehdottaa kokonaisen projektihakemistopuun luontia, joka ei nyt houkuta näin pienellä projektilla, joten skippaan sen ja luon vain tiedoston Chess.hs
. Asennukseni testaamiseksi lisään sinne muutaman yksinkertaisen funktion, kurssin koodausharjoituksista:
module Chess where double :: Integer -> Integer double n = 2 * n factorial :: Integer -> Integer factorial n = if n <= 0 then 1 else n * factorial (n - 1) tribonacci :: Integer -> Integer tribonacci n = tribonacci' 0 0 1 n tribonacci' :: Integer -> Integer -> Integer -> Integer -> Integer tribonacci' _ _ c 1 = c tribonacci' a b c n = tribonacci' b c (a+b+c) (n-1)
Ja ajoin interaktiivisen tulkin, jossa pääsin tätä testaamaan:
$ stack ghci Chess.hs [...] [1 of 1] Compiling Chess ( /.../Chess.hs, interpreted ) Ok, one module loaded. [...] *Chess> double 30 60 *Chess> factorial 10 3628800 *Chess> take 20 (iterate (\n -> n + 1) 1) [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] *Chess> map tribonacci $ take 15 (iterate (\n -> n + 1) 1) [1,1,2,4,7,13,24,44,81,149,274,504,927,1705,3136,5768]
Aion projektissani käyttää vain "standardikirjastoa" eli Prelude-moduulia, niin pitkälti kuin mahdollista. Shakin toteutus alkaa osassa 2.