Jumat, 23 September 2011

Bagaimana menulis program Haskell

Sebuah pengembang 'panduan untuk menciptakan sebuah proyek Haskell baru atau program, dan bekerja di ekosistem pengembang Haskell.
Note: for learning the Haskell language itself we recommend these resources . Catatan: untuk belajar bahasa Haskell sendiri kami merekomendasikan sumber-sumber ini .

Contents Isi

[hide]

1 Recommended tools 1 Rekomendasi alat

Almost all new Haskell projects use the following tools. Hampir semua proyek baru Haskell menggunakan alat berikut. Each is intrinsically useful, but using a set of common tools also helps everyone by increasing productivity, and you're more likely to get patches. Setiap intrinsik bermanfaat, tetapi menggunakan satu set alat umum juga membantu semua orang dengan meningkatkan produktivitas, dan Anda lebih mungkin untuk mendapatkan patch.

1.1 Revision control 1.1 Revisi kontrol

Use git or darcs unless you have a specific reason not to. Gunakan git atau darcs kecuali Anda memiliki alasan tertentu untuk tidak. Both are lightweight distributed revision control systems (and darcs is written in Haskell). Keduanya ringan sistem kontrol terdistribusi revisi (dan darcs ditulis dalam Haskell). Both have massive market share in the Haskell world, if you want to encourage contributions from other Haskell hackers git or darcs are the best. Keduanya memiliki pangsa pasar besar di dunia Haskell, jika Anda ingin mendorong kontribusi dari hacker lainnya git Haskell atau darcs adalah yang terbaik. Darcs hosting is available on code.haskell.org and patch-tag . github for git is very popular. Darcs hosting tersedia di code.haskell.org dan patch-tag . github untuk git sangat populer.

1.2 Build system 1.2 Membangun sistem

Dibangun dengan Cabal
Built with Cabal Dibangun dengan Cabal
Use Cabal . Gunakan Cabal . You should read at least the start of section 2 of the Cabal User's Guide . Anda harus membaca setidaknya awal bagian 2 dari Panduan Pengguna Cabal itu .
You should use cabal-install as a front-end for installing your Cabal library. Anda harus menggunakan kabal-install sebagai front-end untuk menginstal Cabal perpustakaan Anda. Cabal-install provides commands not only for building libraries but also for installing them from, and uploading them to, Hackage. Cabal-instal menyediakan perintah tidak hanya untuk membangun perpustakaan tetapi juga untuk menginstal mereka dari, dan meng-upload ke, Hackage. As a bonus, for almost all programs, it's faster than using Setup.hs scripts directly, since no time is wasted compiling the scripts. Sebagai bonus, untuk hampir semua program, itu lebih cepat daripada menggunakan script Setup.hs secara langsung, karena tidak ada waktu yang terbuang kompilasi script. (This does not apply for programs that use custom Setup.hs scripts, since those need to be compiled even when using cabal-install.) (Ini tidak berlaku untuk program yang menggunakan script kustom Setup.hs, karena membutuhkan mereka untuk dikompilasi bahkan ketika menggunakan Cabal-install.)
cabal-install is widely available, as part of the Haskell Platform , so you can probably assume your users will have it too. komplotan rahasia-instal tersedia secara luas, sebagai bagian dari platform Haskell , sehingga Anda mungkin dapat mengasumsikan pengguna Anda akan memiliki juga.

1.3 Documentation 1.3 Dokumentasi

For libraries, use Haddock . Untuk perpustakaan, gunakan Haddock . We recommend using the version of Haddock that ships with the Haskell Platform. Kami merekomendasikan menggunakan versi Haddock yang dikirimkan dengan Platform Haskell. Haddock generates nice markup , with links to source. Haddock menghasilkan markup yang bagus , dengan link ke sumber.

1.4 Testing 1.4 Pengujian

You can use QuickCheck or SmallCheck to test pure code. Anda dapat menggunakan QuickCheck atau SmallCheck untuk menguji kode murni. To test impure code, use HUnit . Untuk menguji kode murni, gunakan HUnit .
To get started, try Introduction to QuickCheck . Untuk memulai, coba Pengantar QuickCheck . For a slightly more advanced introduction, Simple Unit Testing in Haskell is a blog article about creating a testing framework for QuickCheck using some Template Haskell. Untuk pengantar yang sedikit lebih maju, Pengujian Unit sederhana dalam Haskell adalah artikel blog tentang menciptakan kerangka pengujian untuk QuickCheck menggunakan beberapa Haskell Template. For HUnit, see HUnit 1.0 User's Guide Untuk HUnit, lihat Panduan Pengguna HUnit 1.0

1.5 Distribution 1.5 Distribusi

The standard mechanism for distributing Haskell libraries and applications is Hackage . Mekanisme standar untuk mendistribusikan perpustakaan Haskell dan aplikasi yang Hackage . Hackage can host your cabalised tarball releases, and link to any library dependencies your code has. Hackage dapat host rilis cabalised tarbal Anda, dan link ke setiap dependensi pustaka kode Anda. Users will find and install your packages via "cabal install", and your package will be integrated into Haskell search engines, like hoogle Pengguna akan menemukan dan menginstal paket-paket Anda melalui "organisasi rahasia menginstal", dan paket Anda akan diintegrasikan ke dalam mesin pencari Haskell, seperti hoogle

1.6 Target Environment 1.6 Sasaran Lingkungan

If at all possible, depend on libraries that are provided by the Haskell Platform , and libraries that in turn build against the Haskell Platform. Jika memungkinkan, tergantung pada perpustakaan yang disediakan oleh platform Haskell , dan perpustakaan yang pada gilirannya membangun melawan Platform Haskell. This set of libraries is designed to be widely available, so your end users will be able to build your software. Ini set perpustakaan adalah dirancang untuk menjadi tersedia secara luas, sehingga pengguna akhir Anda akan mampu membangun perangkat lunak Anda.

2 Structure of a simple project 2 Struktur dari proyek sederhana

The basic structure of a new Haskell project can be adopted from HNop , the minimal Haskell project. Struktur dasar dari sebuah proyek Haskell baru dapat diadopsi dari HNop , proyek Haskell minim. It consists of the following files, for the mythical project "haq". Ini terdiri dari file berikut, untuk proyek mitos "haq".
  • Haq.hs -- the main haskell source file Haq.hs - file haskell sumber utama
  • haq.cabal -- the cabal build description haq.cabal - organisasi rahasia membangun deskripsi
  • Setup.hs -- build script itself Setup.hs - membangun script sendiri
  • _darcs -- revision control _darcs - kontrol revisi
  • README -- info README - info
  • LICENSE -- license LISENSI - lisensi
Of course, you can elaborate on this, with subdirectories and multiple modules. Tentu saja, Anda dapat menguraikan ini, dengan subdirektori dan beberapa modul. See Structure of a Haskell project for an example of a larger project's directory structure. Lihat Struktur dari proyek Haskell untuk contoh dari struktur direktori proyek yang lebih besar itu.
Here is a transcript that shows how you'd create a minimal darcs and cabalised Haskell project for the cool new Haskell program "haq", build it, install it and release. Berikut ini adalah transkrip yang menunjukkan bagaimana Anda akan membuat darcs minimal dan cabalised Haskell proyek untuk program baru keren Haskell "haq", membangun itu, menginstalnya dan lepaskan.
Note : The new tool "cabal init" automates all this for you, but you should understand all the parts even so. Catatan: Alat "komplotan init" baru mengotomatiskan semua ini untuk Anda, tetapi Anda harus memahami semua bagian bahkan begitu.
We will now walk through the creation of the infrastructure for a simple Haskell executable. Kita sekarang akan berjalan melalui penciptaan infrastruktur untuk dieksekusi Haskell sederhana. Advice for libraries follows after. Saran untuk perpustakaan berikut setelah.

2.1 Create a directory 2.1 Buat direktori

Create somewhere for the source: Buat suatu tempat untuk source:
$ mkdir haq $ Mkdir haq
$ cd haq $ Cd haq

2.2 Write some Haskell source 2.2 Menulis beberapa sumber Haskell

Write your program: Tulis program anda:
$ cat > Haq . hs $ Cat> Haq. Hs
-- -
-- Copyright (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/~dons/ - Copyright (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/ ~ don /
-- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html) - GPL versi 2 atau kemudian (lihat http://www.gnu.org/copyleft/gpl.html)
-- -
import System . Environment Sistem impor. Lingkungan

-- | 'main' runs the main program - | 'Utama' menjalankan program utama
main :: IO ( ) utama:: IO ()
main = getArgs >>= print . utama = getArgs>> = cetak. haqify . head haqify. kepala

 haqify s = "Haq! " ++ s haqify s = "Haq!" + + s 

2.3 Stick it in darcs 2,3 Tempelkan di darcs

Place the source under revision control (you may need to enter your e-mail address first, to identify you as maintainer of this source): Tempatkan sumber di bawah kontrol revisi (Anda mungkin perlu memasukkan alamat e-mail Anda terlebih dahulu, untuk mengidentifikasi anda sebagai pemelihara dari sumber ini):
$ darcs init $ Darcs init
$ darcs add Haq.hs $ Darcs menambahkan Haq.hs 
$ darcs record $ Darcs catatan
addfile ./Haq.hs addfile / Haq.hs.
Shall I record this change? Haruskah saya merekam perubahan ini? (1/?) [ynWsfqadjkc], or ? (1 /?) [YnWsfqadjkc], atau? for help: y bantuan: y
hunk ./Haq.hs 1 cowok / Haq.hs 1.
+-- + -
+-- Copyright (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/~dons/ + - Hak Cipta (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/ ~ don /
+-- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html ) + - GPL versi 2 atau kemudian (lihat http://www.gnu.org/copyleft/gpl.html )
+-- + -
+import System.Environment + Impor System.Environment
+ +
+-- | 'main' runs the main program + - | 'Utama' menjalankan program utama
+main :: IO () + Utama:: IO ()
+main = getArgs >>= print . + Utama = getArgs>> = cetak. haqify . haqify. head kepala
+ +
+haqify s = "Haq! " ++ s + Haqify s = "Haq!" + + S
Shall I record this change? Haruskah saya merekam perubahan ini? (2/?) [ynWsfqadjkc], or ? (2 /?) [YnWsfqadjkc], atau? for help: y bantuan: y
What is the patch name? Apa nama patch yang? Import haq source Impor haq sumber
Do you want to add a long comment? Apakah Anda ingin menambahkan komentar panjang? [yn]n [Yn] n
Finished recording patch 'Import haq source' Selesai merekam patch 'Impor haq sumber'
And we can see that darcs is now running the show: Dan kita dapat melihat bahwa darcs sekarang menjalankan acara:
$ ls $ Ls
Haq.hs _darcs Haq.hs _darcs

2.4 Add a build system 2,4 Tambahkan membangun sistem

Create a .cabal file describing how to build your project: Buat file komplotan menjelaskan bagaimana untuk membangun proyek Anda.:
$ cat > haq.cabal $ Cat> haq.cabal
Name: haq Nama: haq
Version: 0.0 Versi: 0.0
Description: Super cool mega lambdas Description: Super lambdas mega keren
License: GPL Lisensi: GPL
License-file: LICENSE Lisensi file: LISENSI
Author: Don Stewart Penulis: Don Stewart
Maintainer: dons@cse.unsw.edu.au Maintainer: dons@cse.unsw.edu.au
Build-Type: Simple Membangun-Type: Sederhana
Cabal-Version: >=1.2 Cabal-Version:> = 1,2
Executable haq Executable haq
  Main-is: Haq.hs Main-adalah: Haq.hs
  Build-Depends: base >= 3 && < 5 Build-Depends: basis> = 3 & & <5
(If your package uses other packages, eg haskell98 , you'll need to add them to the Build-Depends: field as a comma separated list.) Add a Setup.hs that will actually do the building: (Jika paket Anda menggunakan paket lain, misalnya haskell98, Anda harus menambahkannya ke Build-Depends: lapangan sebagai daftar dipisahkan koma.) Tambahkan Setup.hs yang benar-benar akan melakukan bangunan:
$ cat > Setup . hs $ Cat> Setup. Hs
import Distribution . Simple Distribusi impor. Sederhana
main = defaultMain utama = defaultMain 
Cabal allows either Setup.hs or Setup.lhs . Cabal memungkinkan baik Setup.hs atau Setup.lhs.
Now would also be a good time to add a LICENSE file and a README file. Sekarang juga akan menjadi saat yang baik untuk menambahkan file LISENSI dan file README. Examples are in the tarball for HNop. Contohnya adalah dalam tarbal untuk HNop.
Record your changes: Rekam perubahan Anda:
$ darcs add haq.cabal Setup.hs LICENSE README $ Darcs menambahkan haq.cabal Setup.hs LISENSI README
$ darcs record --all $ Darcs catatan - semua
What is the patch name? Apa nama patch yang? Add a build system Tambahkan membangun sistem
Do you want to add a long comment? Apakah Anda ingin menambahkan komentar panjang? [yn]n [Yn] n
Finished recording patch 'Add a build system' Patch perekaman selesai 'Tambahkan membangun sistem'

2.5 Build your project 2,5 Membangun proyek Anda

Now build it! Sekarang membangun itu! There are two methods of accessing Cabal functionality: through your Setup.hs script or through cabal-install. Ada dua metode untuk mengakses fungsi Cabal: melalui script Setup.hs Anda atau melalui organisasi rahasia-install. In most cases, cabal-install is now the preferred method. Dalam kebanyakan kasus, komplotan-install sekarang metode yang disukai.
Building using cabal-install: Bangunan menggunakan komplotan rahasia-install:
$ cabal install --prefix=$HOME --user $ Komplotan rahasia menginstal - prefix = $ HOME - pengguna
Building using the traditional Setup.hs method: Membangun menggunakan metode Setup.hs tradisional:
$ runhaskell Setup configure --prefix=$HOME --user $ Runhaskell Pengaturan configure - prefix = $ HOME - pengguna
$ runhaskell Setup build $ Runhaskell Pengaturan membangun
$ runhaskell Setup install $ Runhaskell menginstal Pengaturan
This will install your newly minted haq program in $HOME/bin. Ini akan menginstal program yang Anda baru dicetak haq di $ HOME / bin.

2.6 Run it 2,6 Jalankan

And now you can run your cool project: Dan sekarang Anda dapat menjalankan proyek keren Anda:
$ haq me $ Haq saya
"Haq! me" "Haq! Saya"
You can also run it in-place, even if you skip the install phase: Anda juga dapat menjalankannya di tempat, bahkan jika Anda melewatkan fase menginstal:
$ dist/build/haq/haq you $ Dist / membangun / haq / haq Anda
"Haq! you" "Haq! Anda"

2.7 Build some haddock documentation 2,7 Membangun beberapa dokumentasi haddock

Generate some API documentation into dist/doc/* Menghasilkan beberapa dokumentasi API ke dist / doc / *
Using cabal install: Menggunakan komplotan rahasia menginstal:
$ cabal haddock $ Komplotan rahasia haddock
Traditional method: $ runhaskell Setup haddock Metode Tradisional: $ runhaskell Setup haddock
which generates files in dist/doc/ including: yang menghasilkan file dalam dist / doc / termasuk:
$ w3m -dump dist/doc/html/haq/Main.html
haq Contents Index Isi haq Indeks
Main Utama
Synopsis Ringkasan
main :: IO () utama:: IO ()
Documentation Dokumentasi
main :: IO () utama:: IO ()
main runs the main program utama menjalankan program utama
Produced by Haddock version 0.7 Diproduksi oleh Haddock versi 0.7
No output? Tidak ada output? Make sure you have actually installed haddock. Pastikan Anda telah benar-benar terinstal haddock. It is a separate program, not something that comes with Cabal. Ini adalah program yang terpisah, bukan sesuatu yang datang dengan Cabal. Note that the stylized comment in the source gets picked up by Haddock. Perhatikan bahwa komentar bergaya di source akan dijemput oleh Haddock.

2.8 (Optional) Improve your code: HLint 2.8 (Opsional) Meningkatkan kode Anda: HLint

HLint can be a valuable tool for improving your coding style, particularly if you're new to Haskell. HLint dapat menjadi alat yang berharga untuk meningkatkan gaya koding Anda, terutama jika Anda baru ke Haskell. Let's run it now. Mari kita jalankan sekarang.
$ hlint . $ Hlint.
./Haq.hs:11:1: Warning: Eta reduce / Haq.hs:. 11:01: Peringatan: Eta mengurangi
Found: Ditemukan:
  haqify s = "Haq! " ++ s haqify s = "Haq!" + + s
Why not: Mengapa tidak:
  haqify = ("Haq! " ++) haqify = ("Haq!" + +)
The existing code will work, but let's follow that suggestion. Kode yang sudah ada akan bekerja, tetapi mari kita mengikuti saran itu. Open Haq.hs in your favourite editor and change the line: Buka Haq.hs dalam editor favorit Anda dan mengubah baris:
where haqify s = "Haq! " ++ s mana haqify s = "Haq!" + + s 
to: untuk:
where haqify = ( "Haq! " ++ ) mana haqify = ("Haq!" + +) 

2.9 Add some automated testing: QuickCheck 2,9 Tambahkan beberapa pengujian otomatis: QuickCheck

2.9.1 QuickCheck v1 2.9.1 QuickCheck v1

We'll use QuickCheck to specify a simple property of our Haq.hs code. Kami akan menggunakan QuickCheck untuk menentukan properti sederhana dari kode Haq.hs kami. Create a tests module, Tests.hs, with some QuickCheck boilerplate: Buat modul tes, Tests.hs, dengan beberapa boilerplate QuickCheck:
$ cat > Tests . hs $ Cat> Tes. Hs
import Char impor Char
import List Daftar impor
import Test . QuickCheck Uji impor. QuickCheck
import Text . Printf Teks impor. printf

 main = mapM_ ( \ ( s , a ) -> printf "%-25s: " s >> a ) tests utama = mapM_ (\ (s, a) -> printf "%-25s:" s>> a) tes

instance Arbitrary Char where Misalnya Sewenang-wenang Char mana
    arbitrary = choose ( '\ 0 ' , '\ 128 ' ) sewenang-wenang = memilih ('\ 0', '\ 128')
    coarbitrary c = variant ( ord c ` rem ` 4 ) coarbitrary c = varian (Ord c `rem` 4) 
Now let's write a simple property: Sekarang mari kita menulis properti sederhana:
$ cat >> Tests . hs $ Cat>> Tes. Hs 
-- reversing twice a finite list, is the same as identity - Membalik dua kali daftar terbatas, adalah sama sebagai identitas
prop _ reversereverse s = ( reverse . reverse ) s == id s prop _ reversereverse s = (sebaliknya. reverse) s == id s
    where _ = s :: [ Int ] mana _ = s:: [Int]

-- and add this to the tests list - Dan menambahkan ini ke daftar tes
tests = [ ( "reverse.reverse/id" , test prop _ reversereverse ) ] tes = [("reverse.reverse / id", tes prop _ reversereverse)] 
We can now run this test, and have QuickCheck generate the test data: Kita sekarang dapat menjalankan tes ini, dan telah QuickCheck menghasilkan data uji:
$ runhaskell Tests.hs $ Runhaskell Tests.hs
reverse.reverse/id  : OK, passed 100 tests. reverse.reverse / id: OK, lulus 100 tes.
Let's add a test for the 'haqify' function: Mari kita tambahkan tes untuk fungsi 'haqify':
-- Dropping the "Haq! " string is the same as identity - Menjatuhkan "! Haq" string adalah sama sebagai identitas
prop _ haq s = drop ( length "Haq! " ) ( haqify s ) == id s prop _ haq s = drop (panjang "Haq!") (haqify s) == id s
    where haqify s = "Haq! " ++ s mana haqify s = "Haq!" + + s

 tests = [ ( "reverse.reverse/id" , test prop _ reversereverse ) tes = [("reverse.reverse / id", tes prop _ reversereverse)
        , ( "drop.haq/id" , test prop _ haq ) ] , ("Drop.haq / id", tes prop _ haq)] 
and let's test that: dan mari kita uji bahwa:
$ runhaskell Tests.hs $ Runhaskell Tests.hs
reverse.reverse/id  : OK, passed 100 tests. reverse.reverse / id: OK, lulus 100 tes.
drop.haq/id  : OK, passed 100 tests. drop.haq / id: OK, lulus 100 tes.
Great! Bagus!

2.9.2 QuickCheck v2 2.9.2 QuickCheck v2

If you're using version 2 of QuickCheck, the code in the previous section needs some minor modifications: Jika Anda menggunakan versi 2 dari QuickCheck, kode di bagian sebelumnya membutuhkan beberapa modifikasi kecil:
$ cat > Tests . hs $ Cat> Tes. Hs
import Char impor Char
import List Daftar impor
import Test . QuickCheck Uji impor. QuickCheck
import Text . Printf Teks impor. printf

 main = mapM_ ( \ ( s , a ) -> printf "%-25s: " s >> a ) tests utama = mapM_ (\ (s, a) -> printf "%-25s:" s>> a) tes

-- reversing twice a finite list, is the same as identity - Membalik dua kali daftar terbatas, adalah sama sebagai identitas
prop _ reversereverse s = ( reverse . reverse ) s == id s prop _ reversereverse s = (sebaliknya. reverse) s == id s
    where _ = s :: [ Int ] mana _ = s:: [Int]

-- Dropping the "Haq! " string is the same as identity - Menjatuhkan "! Haq" string adalah sama sebagai identitas
prop _ haq s = drop ( length "Haq! " ) ( haqify s ) == id s prop _ haq s = drop (panjang "Haq!") (haqify s) == id s
    where haqify s = "Haq! " ++ s mana haqify s = "Haq!" + + s

 tests = [ ( "reverse.reverse/id" , quickCheck prop _ reversereverse ) tes = [("reverse.reverse / id", quickCheck prop _ reversereverse)
        , ( "drop.haq/id" , quickCheck prop _ haq ) ] , ("Drop.haq / id", quickCheck prop _ haq)] 

Tidak ada komentar: