Haskellãéã«äœ¿ã
ã¯ããã«
Haskell Advent Calender 2024ã®7æ¥ãã®èšäºã§ãã
ããŠãHaskellã¯ã¢ã«ãããã¯ããããã¯ã·ã§ã³ããããŒãæ¥åžžäœ¿ããªã©æ§ã ãªã·ãŒã³ã§å©çšã§ããŸãã
ãã®èšäºã§ã¯Haskellãé»åãããã®æ°è»œãã§ã«ãžã¥ã¢ã«ã«æ¥åžžäœ¿ãããäžäŸã玹ä»ããŸãã(æšå¹Žã®Advent Calenderã®èšäºãšå 容ãéè€æ°å³ã§ãããä»å¹Žã¯ã¯ãŒã¯ãããŒèŠç¹ã§èšèŒããŠããŸãã)
ãªããšãªããã¢ã«ãŽãªãºã ãæè»œã«è©Šããã
æ¥åžžçã«ãã¡ãã£ãšããã¢ã«ãŽãªãºã ãææ©ã確èªããããæžãæšãŠã®ããã°ã©ã ãããã£ãšäœã£ãŠè©Šãããã·ãŒã³ãããã§ãããããããã®ãšããŸãã
ããã§ã¯è©±ãå°ããããããã«ãç°¡åãªäŸãšããŠæŽæ°ãœãŒãã®ã¢ã«ãŽãªãºã ã詊ããããšããŸãããã
ãšããããæžãæšãŠãŠã¿ã
é ã®äžãçŽã®äžãªã©ã§ããçšåºŠèãããããšããããéã«æžãäžããŠã¿ãŸããããããªãããã®ããã¹ããšãã£ã¿ã§ããã£ãšã³ãŒããæžããŠããŸããŸãããã(ããã¹ããšãã£ã¿ã¯ãã¡ã¢åž³ãªã©ã®ã·ã³ãã«ãªãã®ã§æ§ããŸãããææ©ãé²ããããã«ãIDEã®ã»ããã¢ãããªã©ãå¿ é ã§ã¯ãããŸããã)
qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) = qsort smaller ++ [x] ++ qsort larger
where
smaller = [a | a <- xs, a <= x]
larger = [b | b <- xs, b > x]
ãŸãã¯ã泚ç®ããŠããã³ãŒããæžããŠããŸããŸããããçŸæç¹ã§ã¯ããã¡ã€ã«å
é ã®module宣èšãªã©ã¯äžèŠã§ããã¢ã€ãã¢ã詊ããšãã¯ãã¹ã¢ãŒã«ã¹ã¿ãŒãã§çŽ æ©ãåããäºã«ã䟡å€ããããŸãã
éã«åãããŠã¿ã
ããŠãHaskellã®è¯ãç¹ã®äžã€ã¯ã察話çãªå®è¡ç°å¢(REPL(Read-Eval-Print-Loop))ãæäŸãããŠããç¹ã§ãã(ãã¡ããä»ã«ããäŸãã°Python, Ruby, Scala, JavaScript, ... ãªã©ã®ããã«å¯Ÿè©±ç°å¢ãå©çšå¯èœãªèšèªã®åŠçç³»ããããŸãã)
Haskellã®ããã¡ã¯ãæšæºçãªå¯Ÿè©±ç°å¢ã¯GHCi (GHCâs interactive environment)ã§ããGHCiã¯ãHaskellã®ä»£è¡šçãªã³ã³ãã€ã©ã§ããGHCã«ä»å±ããŠãã察話ç°å¢ã§ã[1]ã
GHCiãçšããããšã§ãå
çšã®ã³ãŒã(Sort1.hs)ã®æåãæè»œãã€è©Šè¡é¯èª€çã«ç¢ºèªã§ããŸããã³ã³ãã€ã«ããã¹ãã³ãŒãã®èšè¿°ã¯äžèŠã§ãã
次ã®ããã«GHCiãèµ·åããŠãå
çšã®ã³ãŒããåãããŠã¿ãŸããããGHCiã®ã³ãã³ãåã¯ãUbuntuãWSL2ç°å¢ã«ãããŠã¯ghciã§ã[2]ã
$ ghci Sort1.hs
以äžã®ããã«è©²åœé¢æ°(qsort)ã«é©åœãªå
¥åãäžããããšã§ã颿°ã®åäœã察話çã«ç¢ºèªã§ããŸãã
ã³ãŒããæžãæç¹ã«ãããŠæ¢ã«å
åã«èšèšãè¡ããŠããå Žåã§ãã£ãŠãã詊è¡é¯èª€çãªç¢ºèªã¯ã³ãŒãã®ç解床ãšå質ãããã«æ·±ããäžã§æå¹ã§ãã
ghci> qsort [1..10]
[1,2,3,4,5,6,7,8,9,10]
ghci> qsort [10,1,5,8,3,2]
[1,2,3,5,8,10]
ãã£ããå ¥åºåã®ä»£è¡šäŸãåŸãããã®ã§ãã¡ã¢ã£ãŠãã
GHCiãçšããŠç¢ºèªãã該åœé¢æ°ã®å ¥åãšåºåã®é¢ä¿ã¯ã颿°ã®æåãçè§£ããäžã§æçã§ããç¹ã«ãåäœå®çžŸã®ããå ¥åºåã®é¢ä¿ã«ã¯äŸ¡å€ããããŸããåŸããã³ãŒããèªã¿è¿ãéã«äŸ¿å©ãªã®ã§ãã³ã¡ã³ãã«ã¡ã¢ããŠãããŸãããããããã¡ã¢ããŠãããªããš10ååŸã«ã¯çµ¶å¯Ÿã«å¿ããŠããèªä¿¡ããããŸãã
-- |
--
-- >>> qsort [10,1,5,8,3,2]
-- [1,2,3,5,8,10]
qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) = qsort smaller ++ [x] ++ qsort larger
where
smaller = [a | a <- xs, a <= x]
larger = [b | b <- xs, b > x]
å é ã®4è¡ã®ã³ã¡ã³ãè¡ã远å ããŸãããããã§ããã®é¢æ°ãåŸã§èªã¿è¿ãéã«é¢æ°ã®æåãããã«çè§£ã§ããŸããããã ã2è¡ã®ã³ã¡ã³ãã®è¿œå ã§ãããå çšã®Sort1.hsãšãã®Sort2.hsãèŠæ¯ã¹ãã°ãqsort颿°ã«èŸŒããäœè ã®æå³ãå°ãæç¢ºã«ãªããŸããã
ãããèªåãã¹ãã§ããŸãã
å
çšè¿œå ããã³ã¡ã³ãã®ãã¡ã3è¡ç®ã®>>>ã§å§ãŸãè¡ã¯ãdoctestã³ãã³ãã«ããèªåãã¹ãã®å¯Ÿè±¡ã«ãªããŸãããšèšããŸããããã®ããã«doctestã®èšæ³ã§ã³ã¡ã³ããæžããŸãããïŒdoctestã¯ãPythonçããHaskellãšã³ã·ã¹ãã ã«åãå
¥ãããããã³ã¡ã³ãäžã«ãã¹ãæç€ºãšçµæãåã蟌ã圢åŒã«ãããã¹ãããŒã«ã§ããïŒ
doctestã³ãã³ããçšããŠããã¡ã€ã«(Sort2.hs)ã«èšèŒãããã³ãŒãããã¹ãããŠã¿ãŸãããã
$ doctest Sort2.hs
Examples: 1 Tried: 1 Errors: 0 Failures: 0
äžèšdoctestã®å®è¡çµæããã¯ããã¹ããæåããããšãåãããŸãã
doctestã¯ããœãŒã¹ãã¡ã€ã«ã®ã³ã¡ã³ãäžã®>>>ã§å§ãŸãè¡ãHaskellã®ããã°ã©ã ãšããŠè§£éããŠå®è¡ãããã®æ¬¡ããã®è¡ãæåŸ
å€ãšããŠãã¹ãçµæãå€å®ããŸãã
ãšããããšã¯ããªãã¡ã¯ã¿ãªã³ã°ããããã®ã§ã¯ãªãã
èªåãã¹ãã§ãããšããããšã¯ãå®å¿ããŠãªãã¡ã¯ã¿ãªã³ã°ãã¢ã€ãã¢ã®è©Šè¡ãè¡ãããã§ããã
ããã§ã¯äžäŸãšããŠã9ã10è¡ç®ã®smallerãšlargerã®å®çŸ©ç®æã«ã€ããŠããªã¹ãå
å
衚èšã«ãã衚çŸããfilter 颿°ã«ãã衚çŸã«å€æŽããã¢ã€ãã¢ã詊ããŠã¿ãŸããïŒãªã¹ãå
å
衚èšããã¡ãªèš³ã§ã¯ãããŸããããããŸã§ãæžãæãã瀺ãããã®äžäŸã§ããïŒ
-- |
--
-- >>> qsort [10,1,5,8,3,2]
-- [1,2,3,5,8,10]
qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) = qsort smaller ++ [x] ++ qsort larger
where
smaller = filter (<= x) xs
larger = filter (> x) xs
doctestãçšããŠããã¹ããåŒãç¶ãæåãããã確èªããŠã¿ãŸãããã
$ doctest Sort3.hs
Examples: 1 Tried: 1 Errors: 0 Failures: 0
ãã¹ãã¯æåããŠããŸããSort3.hsã«ãããã³ãŒãã®æžãæãã¯ãããçšåºŠæ£ãããã§ãã
ããã«ããŠã軜éãªãã¹ãã§çŽ æ©ãäžåãæ€åºã§ããå®å¿æãããã§ãªãã¡ã¯ã¿ãªã³ã°ãæŸé¡ã§ãã
ãããããããªããšãããã¡ãã£ãšãã¹ãããããªã£ãŠãã
ãªã«ããããæãã«ãªã£ãã®ã§ããã該åœé¢æ°(qsort)ããã£ãšè²ã ãªå ¥åã§ãã¹ãããããªã£ãŠããŸããã
ãããããã¹ãçšã®å ¥åãã¿ãŒã³ãæã§äœãã®ã¯é¢åã§ããã©ã¯ãããããã«éã«Haskellã䜿ã£ãŠããã®ã§ãå ¥åãã¿ãŒã³ã倧éã«æäœãããããšã¯çµ¶å¯Ÿã«é¿ãããã
ãšããããšã§ãã¹ãããŒã¿ã®çæããèªåãã¹ãçšã®ããŒã«ã§ããQuickCheckã«ä»»ããŸããããããã«ããã¹ãçµæã®æ£ããã®å€å®ãŸã§ãQuickCheckã«ä»»ããŠããŸããŸãããã
次ã®äŸã®6è¡ç®ã®ããã«ãã³ã¡ã³ãè¡ã«ãã㊠prop> ã§å§ãŸãè¡ãèšè¿°ããããšã«ãããå
¥åããŒã¿ã®çæãšå®è¡çµæã®å€å®ãèªåã§è¡ããŸãã
doctestã¯ãprop>ã§å§ãŸãè¡ãããããã£[4]ã§ãããšè§£éããŠããã®åŠçãQuickCheckã«å§ããŸããQuickCheckã¯ãprop>ã®è¡ã«èšèŒãããã³ãŒãã«å¯ŸããŠãã©ã³ãã ãªå
¥åããŒã¿ãçæããŠããã®å®è¡çµæãå€å®ããŸãã(å®è¡çµæã®å€å®ã¯ãå®è¡çµæãBoolåã«ãããTrueå€ãåŠãã«ãã£ãŠè¡ããŸãã)
-- |
--
-- >>> qsort [10,1,5,8,3,2]
-- [1,2,3,5,8,10]
--
-- prop> qsort xs == Data.List.sort xs
qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) = qsort smaller ++ [x] ++ qsort larger
where
smaller = filter (<= x) xs
larger = filter (> x) xs
äžèšã®äŸã§ã¯ã6è¡ç®ã®prop>ã®è¡ã«ããããqsort xs == Data.List.sort xs ã®éšåããQuickCheckã«æž¡ãããããããã£ã®éšåã§ãã
該åœã³ãŒãã®qsort xs == Data.List.sort xsã«ããã倿°xsã«å¯Ÿããå
¥åããŒã¿ã¯ãQuickCheckãèªåçã«ã©ã³ãã ã«çæããŸãã
ãªããã®äŸã§ã¯ãqsort颿°ã®å®è¡çµæãæšæºã©ã€ãã©ãªã®ãœãŒã颿°(Data.List.sort)ã®çµæãšæ¯ã¹ãããšã§ãçµæã®æ£ãããå€å®ãããŠããŸãã
ã§ã¯ãdoctestãå®è¡ããŠã¿ãŸãããã
$ doctest Sort4.hs
Examples: 2 Tried: 2 Errors: 0 Failures: 0
ãã¹ãã¯æåããŠããŸããqsort颿°ã¯ãã©ã³ãã ãªå
¥åããŒã¿ã«å¯ŸããŠåžžã«qsort xs == Data.List.sort xsãæç«ããŠããŸãããªãQuickCheckã¯ããã©ã«ãã§ã¯ãã©ã³ãã ãªå
¥åããŒã¿åãçšããŠ100åã®ãã¹ããè¡ããŸãã
ãããããæ¬åœã«ãã¹ãã§ããŠããã®ãäžå®ã«ãªã£ãŠãã
ããããQuickCheckã«ããèªåãã¹ããããŸãã«ãæè»œãããŠãæ¬åœã«ãã¹ãã§ããŠããã®ãå¿é
ã«ãªã£ãŠããŸããã
ããã§ãQuickCheckããã°ãæ¬åœã«æ€åºã§ããã®ãã確èªããããã«ããããŠãã¹ãã倱æãããŠã¿ãŸãããã
11è¡ç®ã®smallerã®å®çŸ©ç®æã«ãããæ¡ä»¶åŒãã(<= x) ãã (< x) ã«å€ããŠã¿ãŸãã
-- |
--
-- >>> qsort [10,1,5,8,3,2]
-- [1,2,3,5,8,10]
--
-- prop> qsort xs == Data.List.sort xs
qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) = qsort smaller ++ [x] ++ qsort larger
where
smaller = filter (< x) xs
larger = filter (> x) xs
doctestã³ãã³ããçšããŠããã¹ããå®è¡ããŸãã
$ doctest Sort4ng.hs
Sort4ng.hs:7: failure in expression `qsort xs == Data.List.sort xs'
*** Failed! Falsified (after 6 tests and 2 shrinks):
[3,3]
Examples: 2 Tried: 2 Errors: 0 Failures: 1
æåŸ
éãããã¹ãã倱æããŸãããããã«ããã¹ãã倱æããå Žåã®å
¥åå€ã[3,3]ã§ãã£ãããšã瀺ããŠãããŠããŸãã䟿å©ã§ããã
念ã®çºã«ããã°ãæ··å
¥ãããqsort颿°ãã©ã®ããã«æ¯ãèãããGHCiã䜿ã£ãŠå¯Ÿè©±çã«ç¢ºèªããŠã¿ãŸãããããã¹ãã倱æããå Žåã®å
¥åå€ã§ãã[3,3]ããqsort颿°ã«äžããŠã¿ãŸãã
$ ghci Sort4ng.hs
ghci> qsort [3,3]
[3]
qsort颿°ãç倧ã«ãã°ã£ãŠããŸããå ¥åããŒã¿ã®äžã«åãããŒã¿ãå«ãŸããŠãããšãéè€ããããŒã¿ã倱ããããšãããã°ã§ããããã®äžå ·åãQuickCheckãçšããŠæ€åºã§ããŠããããšãåãããŸããã
ãšããããšã§ããããprop>ã®1è¡ã远å ããã ãã§ãã©ã³ãã ãªå
¥åã«ãããã¹ããå®çŸã§ããŸããã
以äžã®ããã«ãHaskellãéã«äœ¿ã£ãŠã¢ã€ãã¢ãæè»œã«è©Šãããšãšãã«ãããçšåºŠã®å質ã容æã«ç¢ºä¿ã§ãããã§ããããšãåãããŸãããæçã«ã¢ã€ãã¢ã詊ãäžã§ãHaskellãšãã®ç°å¢ã¯äŸ¿å©ã§ããã
ããããããå ¥åããŒã¿ãæ£ããçæãããŠããã®ããå¿é ã«ãªã£ãŠãã
(ãã®ç¯ã¯ãæ¬èšäºã®è¶£æšãšããŠã¯çްããããå 容ãšãªããããé£ã°ããŠããã£ãŠæ§ããŸããã)
ä»åã¯éã«Haskellã䜿ãè¶£æšã®èšäºã§ãã®ã§ãåç¯ãŸã§ã®å 容ã§å åãšèšããŸãã
GHCiã¯è©Šè¡é¯èª€çãªéçºã«åããŠãããdoctestãšQuickCheckã¯èšè¿°ã軜éã§ãããããã¹ãã身è¿ã«ããŸããç¹ã«QuickCheckã¯éè¡çã§ã次ã®1è¡ã远å ããã ãã§ãã©ã³ãã ãªå ¥åããŒã¿ã®çæãšçµæã®ãã§ãã¯ãå šãŠè¡ã£ãŠãããŸããã
-- prop> qsort xs == Data.List.sort xs
ãããäžèšã®ãã¹ãã«ãããŠãQuickCheckãæ£ããç¯å²ã®å ¥åããŒã¿ãæ¬åœã«çæããã®ããå¿é ã«ãªã£ãŠããŸãããäŸãã°ãå ¥åå€ãšããŠ0ã¯çæãããŠããã®ãïŒãè² ã®å€ãçæããã®ãïŒãæå€§å€ã®çæã¯ïŒ ãããããçæããããªã¹ãã®é·ãã¯ã©ãããããªã®ãïŒ
ãããããããããã«è³ããéãªæžãæšãŠããã«ç®ãèããŠããäºå®ãçœæ¥ã®äžã«æãããŠããŸããŸããã
QuickCheckãã©ã®ãããªç¯å²ã§å ¥åå€ãèªåçæãããã®åé¡ã§ã¯ãªããèšèšè ã§ããèªåã¯ãqsort颿°ã®å ¥åå€ã®ç¯å²ãã©ã®ããã«æåŸ ããŠèšèšããã®ãïŒ
ãã®ç¹ãã·ãã¢ã«èããããšã§ãèšèšã®å質ã¯äžæ®µäžããããã§ãããæ©ãæ®µéã§äžå ·åã®èœãã€ãããã§ããã©ã³ãã ãªå ¥åã«ããèªåãã¹ãã¯ãåŠãå¿ã«ããã®èŠç¹ã«èªå°ããŠãããŸãã
æ¬èšäºã¯ãéã«Haskellã䜿ã玹ä»èšäºã§ãããããå
¥åå€ã®ç¯å²ãã©ã®ããã«èšèšãããããŠæ€èšŒãããã«ã€ããŠã¯æ·±ãç«ã¡å
¥ããã«ããããŸã§ãšããŸãã
QuickCheckã䜿ã£ãŠéã«ãã¹ããå§ããã ãã§ãæè³å¯Ÿå¹æãé«ãã®ã§ãæ°è² ããã«QuickCheckãéã«äœ¿ã£ãŠã¿ãŸãããããã£ã1è¡ã®prop>ã§å§ãŸãè¡ã远å ããããšèããã ãã§ããããããåŸãããå¹æã¯æå€ãšå€§ããã§ãã
以äžã§ã¯æè¡çãªåèãšããŠãQuickCheckãã©ã³ãã ãªå ¥åå€ãšããŠã©ã®ãããªå€ãçæããŠãããã確èªããæ¹æ³ãããã€ãç°¡åã«ç޹ä»ããŠãããŸãã
QuickCheckã¯ãã¹ã察象ã§ãã颿°ã®å ¥åã®åã«å¿ããŠãé©åãªã©ã³ãã å€ãèªåã§çæããŸããäŸãã°Intåã®ãªã¹ãã«å¯ŸããŠã¯ãQuickCheckã¯ããã©ã«ãã§æ¬¡ã®ãããªåŸåã®ã©ã³ãã å€ãçæããŸãã
$ ghci
ghci> import Test.QuickCheck
ghci> sample' (arbitrary :: Gen [Int])
[[],[0],[-1],[6],[-1,0],[-8,1,0,-4,5,-3,-8,-4],[9,6,3,-10,11,11,0,7],[8,-8,-8,11,-5,5,10,-11,-5,7,6,3],[-9,-11,6],[],[-16,12,-18,-16,0,13,1,5,-15,6,-3,5,-13,13,12]]
ãŸããä»åã®prop>ã«èšè¿°ããããããã£ã«å¯ŸããŠèªåçã«çæãããå
¥åå€ã®åŸåã¯ãäŸãã°æ¬¡ã®ããã«verboseCheckãªã©ãçšããŠç¢ºèªã§ããŸãã
$ ghci Sort5.hs
ghci> import Test.QuickCheck
ghci> verboseCheck $ (\xs -> qsort xs == Data.List.sort xs)
Passed:
[]
Passed:
[0]
(äžç¥)
Passed:
[10,-57,-24,16,-41,-16,52,-93,90,-62,-36,-79,46,73,43,6,73,-21,88,-57,-18,54,-42,0,-69,80,76,79,-55,1,-75,98,-98]
+++ OK, passed 100 tests.
ããã«ããã蟌ã¿å
¥ã£ãŠããŸãããå
¥åå€ã®çµ±èšã®ãããªãã®ãcollectãªã©ãçšããŠç¢ºèªã§ããŸãã
$ ghci Sort5.hs
ghci> import Test.QuickCheck
ghci> quickCheck $ (\xs -> collect xs (qsort xs == Data.List.sort xs))
+++ OK, passed 100 tests:
4% []
2% [1]
1% [-10,18,18,-17,10,-16,-28,-25,22,27,-27,25,28,-12,8,-12,-20,-8,29,3,16,17,20,27,-5,-28]
1% [-10,4,15,39,11,-29,51,25,-57,29,-4,-46,-8,-31,22]
:
æ¬èšäºã§ã¯QuickCheckã®è©³çްã«ã¯ãã以äžç«ã¡å ¥ããŸããããå ¥åå€ã®å¶åŸ¡æ¹æ³ãªã©ã詳ããç¥ãããæ¹ã¯ãèšäºæ«å°Ÿã®åèæ å ±ã®ãªã³ã¯ããQuickCheckã®ä»æ§ãªã©ãåç §ããŠãã ããã
ãªããè¯ãæãã«ãªã£ãŠããã äœ¿ãæšãŠã ãã©ãããã¥ã¡ã³ãåããŠããã
ãšããããšã§ãHaskellã®ã³ãŒããéã«æžããŠãæåã詊ããŠãç°¡æãªãã¹ãã«ãã£ãŠããçšåºŠã®å質ãçŽ æ©ãåŸãããšããéãªäœ¿ãæ¹ã®ç޹ä»ã¯ä»¥äžãšãªããŸãã
ããããã¯å¿ é ã®å 容ã§ã¯ç¡ãã®ã§ããããã£ããã§ãã®ã§ç¶ºéºãªèŠæ ãã®ããã¥ã¡ã³ããçæããŠãã®èšäºã®çµã³ãšããŸããããã¥ã¡ã³ãçæããŒã«ã®haddockãçšããŠãäŸç€ºããã³ãŒãã«ã€ããŠHTML圢åŒã®ããã¥ã¡ã³ããçæããŠã¿ãŸãããã
以äžã®ããã«ãã³ãŒãã®ã¢ãžã¥ãŒã«æ§é ãhaddockãçè§£ã§ããããã«ããã¡ã€ã«ã®åé ã«module宣èšã®è¡ã远å ããŠãããŸãã
module Sort where
-- | Sort with pivot
--
-- >>> qsort [10,1,5,8,3,2]
-- [1,2,3,5,8,10]
--
-- prop> qsort xs == Data.List.sort xs
qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) = qsort smaller ++ [x] ++ qsort larger
where
smaller = filter (<= x) xs
larger = filter (> x) xs
ãã®äžã§ã次ã®ããã«haddockã³ãã³ããå®è¡ããŸãã
ãã®äŸã§ã¯ãdistãã£ã¬ã¯ããªã®äžã«HTML圢åŒã®ããã¥ã¡ã³ããçæãããŸãã
$ haddock --html --hyperlinked-source -o dist Sort5.hs
次ã®ãããªç¶ºéºãªèŠæ ãã§ãHTML圢åŒã®ããã¥ã¡ã³ããçæãããŸãã

ãããŠSource衚瀺ã®ããŒãžã§ã¯ãããŠã¹ã«ãŒãœã«ã颿°ãªã©ã®äžã«ä¹ãããšãåã®æ å ±ãªã©ã衚瀺ãããŠäŸ¿å©ã§ãã

èŠæ ããè¯ãã®ã§ãããã«ã³ã¡ã³ããã¡ãããšæžããããªã£ãŠããŸããã
ãããéãªäœ¿ãæšãŠã³ãŒããªã®ã§ããã®èšäºã§ã¯ãããŸã§ãšããŸãã
(å°ãã ãè£è¶³) ããããã°ãããã°ã©ã å šäœãéã«å®è¡ãããããšããã
åç¯ã§æåŸãšèšã£ãã®ã§ãããããšïŒç¹ã ãHaskellãéã«äœ¿ãããã®è£è¶³ã§ãã
颿°åäœã§ã¯ãªããŠãããã°ã©ã å šäœãéã«å®è¡ãããå ŽåããããããããŸããã
main颿°ãå«ãããã°ã©ã å
šäœã察話çã«è©Šãããå Žåã«ã¯ã次ã®ããã«GHCiå
ã§:mainã³ãã³ãã䜿ããšè¯ãã§ãããã(å®è¡æã«åŒæ°ãäžããå¿
èŠãããå Žåã«ã¯ã:mainã«ç¶ããŠèšè¿°ã§ããŸã[5]ã)
$ ghci Hello.hs
ghci> :main
hello, world
ããã°ã©ã å
šäœãéã«å®è¡ããä»ã®æ¹æ³ãšããŠã次ã®ããã«runhaskellã³ãã³ããçšããŠããã°ã©ã ãã¹ã¯ãªããçã«å®è¡ããæ¹æ³ããããŸã[6]ã runhaskellã³ãã³ãã¯ãHaskellã®ä»£è¡šçãªã³ã³ãã€ã©ã§ããGHCã«ä»å±ããŠããã¹ã¯ãªããå®è¡çšã®ã³ãã³ãã§ãã
次ã®ããã«ãæç€ºçãªã³ã³ãã€ã«éçšãçµãã«Haskellããã°ã©ã ãçŽæ¥çã«å®è¡ã§ããŸããHaskellããã°ã©ã ãéã«CLIã³ãã³ããšããŠäœ¿ãå Žåãªã©ã«é©ããŠããŸãã
$ runhaskell Hello.hs
hello, world
ããŠæ¬åœã®æåŸã®æåŸãšããŠãããŸãã§ãã
ãã¯ãGHCiã®èµ·åãé¢åãããããããã¹ããšãã£ã¿ãéãã®ãé¢åãªãšãããããmain颿°ãæžãã®ããé¢åãããïŒ
ãããªçŽ æŽãããéãªäœ¿ãæ¹ã®ããã«ãGHCã³ã³ãã€ã©ã®åŒè©äŸ¡ã¢ãŒã(Expression evaluation mode)ããããŸãã
Haskellã®GHCã³ã³ãã€ã©ã-eãªãã·ã§ã³ä»ãã§å®è¡ãããšã-eãªãã·ã§ã³ã«ç¶ãHaskellã®ã³ãŒããçŽæ¥çã«å®è¡ã§ããŸãã以äžã®ããã«Haskellãã¯ã³ã©ã€ããŒé¢šã«å®è¡ã§ããŸã[7]ã
$ ghc -e 'putStrLn "hello, world"'
hello, world
ãã®-eã«ç¶ãåŒæ°ã«ã¯ãHaskellã®åŒãªãäœã§ãèšè¿°ã§ããŸã[8]ã ãã¯ãæ¬çã®å
容ããé¢ããŠãããŠGHCiãdoctestãQuickCheckãç»å ŽããŠããªãäŸã§ããããšã«ããHaskellã¯éã«äœ¿ããŸãããããããã§ã¯åããæç€ºããŠããŸããããéãªã®ã§è¯ãã
$ ghc -e "[n^2 | n <- [0..4]]"
[0,1,4,9,16]
$ ghc -e '"hello, world"'
"hello, world"
ããã«æ¬¡ã®ããã«ãã¡ã€ã«ãèªã¿èŸŒãŸããŠããã®ãã¡ã€ã«å
ã®é¢æ°ãå®è¡ããããšãã§ããŸãã main颿°ã¯äžèŠã§ãçŽç²é¢æ°ã ãã®ã³ãŒããçŽæ¥çã«å®è¡ã§ããŸãã
$ ghc -e "qsort [5,1,2]" Sort1.hs
[1,2,5]
ããã話ããããŸããã æ°ããšããªãããŠããŸãšãã§ãã
ãŸãšã
Haskellã¯ãéãªæ¥åžžäœ¿ãã«ãè¯ãæãã§äœ¿ããŸãã
ãšã«ããghciã³ãã³ããšdoctestã³ãã³ãããæå
ã«ããã°ãæ§ã
ãªã¢ã€ãã¢ããã€ã§ãæ°è»œã«è©ŠããŸãã
ãã¹ãçšã®ãã©ã€ãçãå¿
èŠãšããã«ã³ãŒãã®æåã詊è¡é¯èª€çã«ç¢ºèªã§ãã察話ç°å¢ã¯ãã¢ã€ãã¢ããšãããã詊ããŠã¿ãããšããæ°æã¡ãåŸæŒãããŠãããŸãã
è€éãªèšè¿°ãå¿
èŠãšããã«è»œéã«ãã¹ããè¡ããä»çµã¿ã¯ããªãã¡ã¯ã¿ãªã³ã°ã容æã«ãããšãšãã«ãæ¥åžžçãªãã¹ãã«å¯ŸããããŒãã«ãäžããŠãããŸãããã¹ãã«å¿
èŠãªã®ã¯ãã³ã¡ã³ãäžã« >>> ã prop> ã®è¡ãèšè¿°ããããšã ãã§ãã
ãšããããšã§æ¬èšäºãç· ãããããŸãã
ã¢ã€ãã¢ãæ°è»œã«è©ŠãããæžãæšãŠã®ããã°ã©ã ãçŽ æ©ãäœãããã·ãŒã³ã§ã¯ã以äžã®æ©èœãªã©ãæå¹ã§ãã
- GHCi (察話çãªå®è¡ç°å¢)
- doctest (ã³ã¡ã³ã圢åŒã«ããèªåãã¹ã)
- QuickCheck (ãã¹ãããŒã¿ã®èªåçæãšãã¹ãã®èªåå€å®)
ãããã¯ãHaskell(ã®èšèªä»æ§ãšåŠçç³»)ã ãã®ç¹åŸŽã§ã¯ãããŸããããHaskellãè¯ãæãã§éã«äœ¿ããŸããHaskellã䜿ãå§ããäžã§åã·ã¹ãã ãã¢ããçã®çè§£ã¯(é¢çœãããã©ã)å¿ é ã§ã¯ç¡ãã®ã§ãã«ãžã¥ã¢ã«ãªè»œãæãã§ãHaskellãéã«äœ¿ã£ãŠã¿ãŸããã[9]ã
ã§ã¯ãHappy Haskelling!
åèæ å ±ãªã©
-
Haskellã®ç°å¢æ§ç¯2023 (Haskellã®åŠçç³»ã®ã€ã³ã¹ããŒã«ãç°å¢æ§ç¯æ¹æ³)
-
Haskellèšèªã®å ¬åŒãµã€ã
-
GHCã³ã³ãã€ã©ã®ãŠãŒã¶ãŒãºã¬ã€ã (GHC, GHCi, runhaskell, ghc -e ã®èª¬æ)
-
doctestã®å ¬åŒæ å ±
-
QuickCheckã®å ¬åŒæ å ±
-
Haddockã®å ¬åŒæ å ±
-
Haskellã§ã¡ãã£ãšããã¹ã¯ãªãããæžã (runhaskellã®å®è·µçãªç޹ä»èšäº)
-
ãããžã§ã¯ããäœããã«Haskellããã (éã ãã©ã©ã€ãã©ãªãããŒãžã§ã³ç®¡çããããªã£ãã)
-
æšå¹Ž2023幎ã®Advent Calenderã®èšäº (doctestãšQuickCheckã®ç°¡æçãªç޹ä»èšäº)
-
æ¬èšäºã§ç޹ä»ããã³ãŒãäŸ (GitHubã®ãªããžããª)
-
GHCiãã€ã³ã¹ããŒã«ããæ¹æ³ã¯ãäŸãã°ãhttps://zenn.dev/mod_poppo/articles/haskell-setup-2023 ãåç §ããŠãã ããã â©ïž
-
æ¬èšäºã®ã³ãã³ãã®å®è¡äŸã¯ãUbuntuãŸãã¯Windowsã®WSL2ç°å¢ã«ãããæäœäŸã§ãã â©ïž
-
tinfoã©ã€ãã©ãªã®äžè¶³ã«ãããšã©ãŒãåºãå Žåã«ã¯ã次ã®ããã«ããŠlibtinfoãã€ã³ã¹ããŒã«ããããšã§ãšã©ãŒãè§£æ¶ã§ããå ŽåããããŸãã
$ sudo apt install libtinfo-devâ©ïž -
ããã§ã¯ãããããã£ãšã¯ãæºããã¹ã仿§ãçåœå€ã«ãã£ãŠå€å®å¯èœã«èšè¿°ããå®è¡å¯èœãªã³ãŒããšããŠãããŸãã â©ïž
-
ghciã®åã³ãã³ãã®äœ¿ãæ¹ãå¿ããå Žåã«ã¯ãghciå ã§ghci> :helpã®ããã«ã³ãã³ããå®è¡ãããšç°¡åãªãã«ãã衚瀺ãããŸãã â©ïž -
runhaskellã³ãã³ãã«ã¯ãrunghcã³ãã³ããšããå¥åããããŸãã ã©ã€ãã©ãªã®äŸåé¢ä¿ã倿§ãªç¶æ³ã§runhaskellãããŸãäœ¿ãæ¹æ³ã«ã€ããŠã¯ããã¡ãã®èšäºãåèã«ãªããŸããhttps://zenn.dev/mod_poppo/articles/haskell-script â©ïž -
ghc -eã§Haskellãã¯ã³ã©ã€ããŒé¢šã«äœ¿çšããäŸã¯ããã¡ããåç §ããŠãã ãããhttps://github.com/takenobu-hs/commandline-haskell â©ïž -
å®ã¯
ghc -eã¯å éšçã«GHCiã䜿çšããŠããã®ã§ã-eã«ç¶ãæååã«ã¯GHCiã«æž¡ãã³ãã³ããªãäœã§ãäžããããŸãã äŸãã°ãghc -e ':t foldl'ã®ããGHCiã®ãµãã³ãã³ããå©çšå¯èœã§ãã â©ïž -
ãªããšãHaskell(GHC)ã®åŠçç³»ãã€ã³ã¹ããŒã«ããããšããé¢åãããïŒ ããã§ãããããã§ããéïŒãã®ãããªå Žåã¯ãHaskell.orgãå ¬åŒã«æäŸããŠããWebçã®Playgroundç°å¢ã§ãéã«éã³å§ããŸããããhttps://play.haskell.org/ â©ïž
Discussion