Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π˜Π·ΡƒΡ‡Π°ΠΉ Haskell Π²ΠΎ имя Π΄ΠΎΠ±Ρ€Π°!Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 24

Автор ΠœΠΈΡ€Π°Π½ Π›ΠΈΠΏΠΎΠ²Π°Ρ‡Π°

Пока всё Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. Но Ρ‡Ρ‚ΠΎ Ссли ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚ΠΎ ΠΆΠ΅ самоС для списка, содСрТащСго, спасибо Π΄ΠΎΠΊΡ‚ΠΎΡ€Ρƒ Π—Π»ΠΎ, ΠΎΠ΄ΠΈΠ½ ΠΌΠΈΠ»Π»ΠΈΠΎΠ½ Π΅Π΄ΠΈΠ½ΠΈΡ†?

ghci> foldl (+) 0 (replicate 1000000 1)

*** Exception: stack overflow



Ого, ТСстоко! Π§Ρ‚ΠΎ ΠΆΠ΅ ΡΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ? Haskell Π»Π΅Π½ΠΈΠ², поэтому ΠΎΠ½ ΠΎΡ‚ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π΅Ρ‚ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Π΅ вычислСния Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ, насколько Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Когда ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ foldl, Haskell Π½Π΅ вычисляСт аккумулятор Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ шагС. ВмСсто этого ΠΎΠ½ ΠΎΡ‚ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π΅Ρ‚ вычислСниС. На ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ шагС ΠΎΠ½ снова Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ считаСт, ΠΎΠΏΡΡ‚ΡŒ откладывая Π½Π° ΠΏΠΎΡ‚ΠΎΠΌ. Π•ΠΌΡƒ, ΠΏΡ€Π°Π²Π΄Π°, приходится ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒ староС ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ вычислСниС Π² памяти, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½ΠΎΠ²ΠΎΠΌΡƒ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π΅Π³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΏΠΎΠΊΠ° свёртка foldl радостно торопится ΠΏΠΎ списку, Π² памяти образуСтся ΠΊΡƒΡ‡Π° ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… вычислСний, ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ±ΡŠΡ‘ΠΌ памяти. Π Π°Π½ΠΎ ΠΈΠ»ΠΈ ΠΏΠΎΠ·Π΄Π½ΠΎ это ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ ошибкС пСрСполнСния стСка.

Π’ΠΎΡ‚ ΠΊΠ°ΠΊ Haskell вычисляСт Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ foldl (+) 0 [1,2,3]:

foldl (+) 0 [1,2,3] =

foldl (+) (0 + 1) [2,3] =

foldl (+) ((0 + 1) + 2) [3] =

foldl (+) (((0 + 1) + 2) + 3) [] =

((0 + 1) + 2) + 3 =

(1+2) + 3 =

3 + 3 =

6

Π—Π΄Π΅ΡΡŒ Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ сначала строится большой стСк ΠΈΠ· ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… вычислСний. Π—Π°Ρ‚Π΅ΠΌ, ΠΏΠΎ достиТСнии ΠΊΠΎΠ½Ρ†Π° списка, Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ΡΡ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Π΅ вычислСния. Для ΠΌΠ°Π»Π΅Π½ΡŒΠΊΠΈΡ… списков Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π½Π΅Ρ‚, Π° Π²ΠΎΡ‚ Ссли список Π³Ρ€ΠΎΠΌΠ°Π΄Π½Ρ‹ΠΉ, с ΠΌΠΈΠ»Π»ΠΈΠΎΠ½ΠΎΠΌ элСмСнтов ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ большС, Π²Ρ‹ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ стСка. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ всС эти ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ вычислСния Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ рСкурсивно. Π‘Ρ‹Π»ΠΎ Π±Ρ‹ Π½Π΅ΠΏΠ»ΠΎΡ…ΠΎ, Ссли Π±Ρ‹ сущСствовала функция, которая вычислСния Π½Π΅ ΠΎΡ‚ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π΅Ρ‚, ΠΏΡ€Π°Π²Π΄Π° ΠΆΠ΅? Она Π±Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π»Π° ΠΊΠ°ΠΊ-Ρ‚ΠΎ Ρ‚Π°ΠΊ:

foldl' (+) 0 [1,2,3] =

foldl' (+) 1 [2,3] =

foldl' (+) 3 [3] =

foldl (+) 6 [] =

6

ВычислСния ΠΌΠ΅ΠΆΠ΄Ρƒ шагами свёртки Π½Π΅ ΠΎΡ‚ΠΊΠ»Π°Π΄Ρ‹Π²Π°ΡŽΡ‚ΡΡ – ΠΎΠ½ΠΈ Ρ‚ΡƒΡ‚ ΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ. Ну Ρ‡Ρ‚ΠΎ ΠΆ, Π½Π°ΠΌ ΠΏΠΎΠ²Π΅Π·Π»ΠΎ: строгая вСрсия Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ foldl Π² ΠΌΠΎΠ΄ΡƒΠ»Π΅ Data.List Π΅ΡΡ‚ΡŒ, ΠΈ называСтся ΠΎΠ½Π° ΠΈΠΌΠ΅Π½Π½ΠΎ foldl'. ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ-ΠΊΠ° с Π΅Ρ‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ сумму ΠΌΠΈΠ»Π»ΠΈΠΎΠ½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†:

ghci> foldl' (+) 0 (replicate 1000000 1)

1000000

ΠŸΠΎΡ‚Ρ€ΡΡΠ°ΡŽΡ‰ΠΈΠΉ успСх! Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ, Ссли, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ foldl, ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΎΡˆΠΈΠ±ΠΊΡƒ пСрСполнСния стСка, ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ Π½Π° foldl'. ΠšΡΡ‚Π°Ρ‚ΠΈ, Ρƒ foldl1 Ρ‚ΠΎΠΆΠ΅ Π΅ΡΡ‚ΡŒ строгая вСрсия, ΠΎΠ½Π° называСтся foldl1'.

ΠŸΠΎΠΈΡ‰Π΅ΠΌ числа


Π’Ρ‹ ΠΏΡ€ΠΎΠ³ΡƒΠ»ΠΈΠ²Π°Π΅Ρ‚Π΅ΡΡŒ ΠΏΠΎ ΡƒΠ»ΠΈΡ†Π΅, ΠΈ Ρ‚ΡƒΡ‚ ΠΊ Π²Π°ΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ ΡΡ‚Π°Ρ€ΡƒΡˆΠΊΠ° ΠΈ ΡΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚: Β«ΠŸΡ€ΠΎΡΡ‚ΠΈΡ‚Π΅, Π° ΠΊΠ°ΠΊΠΎΠ²ΠΎ ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π½Π°Ρ‚ΡƒΡ€Π°Π»ΡŒΠ½ΠΎΠ΅ число, сумма Ρ†ΠΈΡ„Ρ€ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Ρ€Π°Π²Π½Π° 40?Β»

Ну Ρ‡Ρ‚ΠΎ, ΡΠ΄ΡƒΠ»ΠΈΡΡŒ? Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ Haskell-магию ΠΈ Π½Π°ΠΉΠ΄Ρ‘ΠΌ это число. Если ΠΌΡ‹, ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, просуммируСм Ρ†ΠΈΡ„Ρ€Ρ‹ числа 123, Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ 6. Π£ ΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΆΠ΅ числа Ρ‚ΠΎΠ³Π΄Π° сумма Ρ†ΠΈΡ„Ρ€ Ρ€Π°Π²Π½Π° 40?

ΠŸΠ΅Ρ€Π²Ρ‹ΠΌ Π΄Π΅Π»ΠΎΠΌ напишСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая считаСт сумму Ρ†ΠΈΡ„Ρ€ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ числа. Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ…ΠΈΡ‚Ρ€Ρ‹ΠΉ Ρ‚Ρ€ΡŽΠΊ! Π’ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ show ΠΈ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ нашС число Π² строку. Когда Ρƒ нас Π±ΡƒΠ΄Π΅Ρ‚ строка ΠΈΠ· Ρ†ΠΈΡ„Ρ€, ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Ρ‘ΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π΅Ρ‘ символ Π² число ΠΈ просуммируСм ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ²ΡˆΠΈΠΉΡΡ числовой список. ΠŸΡ€Π΅Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ символ Π² число Π±ΡƒΠ΄Π΅ΠΌ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ digitToInt ΠΈΠ· модуля Data.Char. Она ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Char ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Int:

ghci> digitToInt '2'

2

ghci> digitToInt 'F'

15

ghci> digitToInt 'z'

*** Exception: Char.digitToInt: not a digit 'z'

Ѐункция digitToInt Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с символами ΠΈΠ· Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π° ΠΎΡ‚ '0' Π΄ΠΎ '9' ΠΈ ΠΎΡ‚ 'A' Π΄ΠΎ 'F' (Ρ‚Π°ΠΊΠΆΠ΅ ΠΈ строчными).

Π’ΠΎΡ‚ функция, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π°Ρ число ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰Π°Ρ сумму Π΅Π³ΠΎ Ρ†ΠΈΡ„Ρ€:

import Data.Char

import Data.List


digitSum :: Int -> Int

digitSum = sum . map digitToInt . show

ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ Π·Π°Π΄Π°Π½Π½ΠΎΠ΅ число Π² строку, пройдёмся ΠΏΠΎ строкС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ digitToInt, суммируСм ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ²ΡˆΠΈΠΉΡΡ числовой список.



Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½ΡƒΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π½Π°Ρ‚ΡƒΡ€Π°Π»ΡŒΠ½ΠΎΠ΅ число, ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠ² ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ digitSum ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° число 40. Для этого Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ find ΠΈΠ· модуля Data.List. Она ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ ΠΈ список ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ элСмСнт списка, ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰ΠΈΠΉ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚Ρƒ. ΠŸΡ€Π°Π²Π΄Π°, Ρ‚ΠΈΠΏ Ρƒ Π½Π΅Ρ‘ нСсколько Π½Π΅ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ:

ghci> :t find

find :: (a -> Bool) -> [a] -> Maybe a

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ – ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚, Π²Ρ‚ΠΎΡ€ΠΎΠΉ – список, с этим всё ясно. Но Ρ‡Ρ‚ΠΎ с Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ? Π§Ρ‚ΠΎ это Π·Π° Maybe a? Π­Ρ‚ΠΎ Ρ‚ΠΈΠΏ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π°ΠΌ Π΄ΠΎ сих ΠΏΠΎΡ€ Π½Π΅ встрСчался. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с Ρ‚ΠΈΠΏΠΎΠΌ Maybe a Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ…ΠΎΠΆΠ΅ Π½Π° список Ρ‚ΠΈΠΏΠ° [a]. Если список ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ноль, ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ элСмСнтов, Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Maybe a ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ ноль элСмСнтов, Π»ΠΈΠ±ΠΎ Π² точности ΠΎΠ΄ΠΈΠ½. Π­Ρ‚Ρƒ ΡˆΡ‚ΡƒΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, Ссли ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΡ€Π΅Π΄ΡƒΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ²Π°Π»Π°. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ содСрТит, – Nothing. Оно Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ пустому списку. Для конструирования значСния, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ содСрТит, скаТСм, строку "эй", Π±ΡƒΠ΄Π΅ΠΌ ΠΏΠΈΡΠ°Ρ‚ΡŒ Just "эй". Π’ΠΎΡ‚ ΠΊΠ°ΠΊ всё это выглядит:

ghci> Nothing

Nothing

ghci> Just "эй"

Just "эй"

ghci> Just 3

Just 3

ghci> :t Just "эй"

Just "эй" :: Maybe [Char]

ghci> :t Just True

Just True :: Maybe Bool

Π’ΠΈΠ΄ΠΈΡ‚Π΅, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Just True ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ Maybe Bool. ΠŸΠΎΡ…ΠΎΠΆΠ΅ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ список, содСрТащий значСния Ρ‚ΠΈΠΏΠ° Bool, ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ [Bool].

Если функция find Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ элСмСнт, ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰ΠΈΠΉ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚Ρƒ, ΠΎΠ½Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ этот элСмСнт, ΠΎΠ±Ρ‘Ρ€Π½ΡƒΡ‚Ρ‹ΠΉ Π² Just. Если Π½Π΅ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Nothing:

ghci> find (>4) [3,4,5,6,7]

Just 5

ghci> find odd [2,4,6,8,9]

Just 9

ghci> find (=='x') "ΠΌΠ΅Ρ‡-ΠΊΠ»Π°Π΄Π΅Π½Π΅Ρ†"

Nothing

ВСрнёмся Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΊ нашСй Π·Π°Π΄Π°Ρ‡Π΅. ΠœΡ‹ ΡƒΠΆΠ΅ написали Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ digitSum ΠΈ Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΎΠ½Π° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΡˆΠ»Π° ΠΏΠΎΡ€Π° ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ всё вмСстС. Напомню, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ Π½Π°ΠΉΡ‚ΠΈ число, сумма Ρ†ΠΈΡ„Ρ€ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Ρ€Π°Π²Π½Π° 40.

firstTo40 :: Maybe Int

firstTo40 = find (\x -> digitSum == 40) [1..]

ΠœΡ‹ просто взяли бСсконСчный список [1..] ΠΈ Π½Π°Ρ‡Π°Π»ΠΈ ΠΈΡΠΊΠ°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π²ΠΎΠ΅ число, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ digitSum для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Ρ€Π°Π²Π½ΠΎ 40.

ghci> firstTo40

Just 49999

А Π²ΠΎΡ‚ ΠΈ ΠΎΡ‚Π²Π΅Ρ‚! МоТно ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ±Ρ‰ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠΎΠΌΡƒΡŽ сумму Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°:

firstTo :: Int -> Maybe Int

firstTo n = find (\x -> digitSum x == n) [1..]

И нСбольшая ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°:

ghci> firstTo 27

Just 999

ghci> firstTo 1

Just 1

ghci> firstTo 13

Just 49

ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡Π΅ΠΉ Π½Π° значСния

Π—Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ, работая с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΈΠ· Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π½Π°Π±ΠΎΡ€Π°, ΠΌΡ‹ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π½Π΅ заботимся, Π² ΠΊΠ°ΠΊΠΎΠΌ порядкС ΠΎΠ½ΠΈ располоТСны. ΠœΡ‹ просто Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΊ Π½ΠΈΠΌ доступ ΠΏΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΊΠ»ΡŽΡ‡Ρƒ. НапримСр, ТСлая ΡƒΠ·Π½Π°Ρ‚ΡŒ, ΠΊΡ‚ΠΎ ΠΆΠΈΠ²Ρ‘Ρ‚ ΠΏΠΎ извСстному адрСсу, ΠΌΡ‹ ΠΈΡ‰Π΅ΠΌ ΠΈΠΌΠ΅Π½Π° Ρ‚Π΅Ρ…, ΠΊΡ‚ΠΎ ΠΏΠΎ этому адрСсу ΠΏΡ€ΠΎΠΆΠΈΠ²Π°Π΅Ρ‚. Π’ ΠΎΠ±Ρ‰Π΅ΠΌ случаС ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΡ‰Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ (Ρ‡ΡŒΡ‘-Π»ΠΈΠ±ΠΎ имя) ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ (адрСс этого Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠ°).

ΠŸΠΎΡ‡Ρ‚ΠΈ Ρ…ΠΎΡ€ΠΎΡˆΠΎ: ассоциативныС списки

БущСствуСт ΠΌΠ½ΠΎΠ³ΠΎ способов ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Β«ΠΊΠ»ΡŽΡ‡β€“Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅Β». Один ΠΈΠ· Π½ΠΈΡ… – ассоциативныС списки. АссоциативныС списки (Ρ‚Π°ΠΊΠΆΠ΅ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹Π΅ словарями ΠΈΠ»ΠΈ отобраТСниями) – это списки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ хранят нСупорядочСнныС ΠΏΠ°Ρ€Ρ‹ Β«ΠΊΠ»ΡŽΡ‡β€“Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅Β». НапримСр, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ ассоциативныС списки для хранСния Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½Π½Ρ‹Ρ… Π½ΠΎΠΌΠ΅Ρ€ΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½Π½Ρ‹ΠΉ Π½ΠΎΠΌΠ΅Ρ€ ΠΊΠ°ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ имя Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠ° ΠΊΠ°ΠΊ ΠΊΠ»ΡŽΡ‡. Нам Π½Π΅Π²Π°ΠΆΠ½ΠΎ, Π² ΠΊΠ°ΠΊΠΎΠΌ порядкС ΠΎΠ½ΠΈ сохранСны: всё, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ трСбуСтся, – ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½Π½Ρ‹ΠΉ Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ. НаиболСС простой способ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ассоциативный список Π² языкС Haskell – ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ список ΠΏΠ°Ρ€. ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΏΠ°Ρ€Ρ‹ Π±ΡƒΠ΄Π΅Ρ‚ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ, Π²Ρ‚ΠΎΡ€ΠΎΠΉ – Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ. Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ассоциативного списка с Π½ΠΎΠΌΠ΅Ρ€Π°ΠΌΠΈ Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½ΠΎΠ²:

phoneBook =

  [("оля","555–29-38")

  ,("ТСня","452–29-28")

  ,("катя","493–29-28")

  ,("маша","205–29-28")

  ,("надя","939–82-82")

  ,("юля","853–24-92")

  ]

Π—Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ странного выравнивания, это просто список, состоящий ΠΈΠ· ΠΏΠ°Ρ€ строк. Бамая частая Π·Π°Π΄Π°Ρ‡Π° ΠΏΡ€ΠΈ использовании ассоциативных списков – поиск Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ значСния ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ. Π”Π°Π²Π°ΠΉΡ‚Π΅ напишСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для этой Π·Π°Π΄Π°Ρ‡ΠΈ.

findKey :: (Eq k) => k –> [(k,v)] –> v

findKey key xs = snd . head $ filter (\(k,v) –> key == k) xs

Всё довольно просто. Ѐункция ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΊΠ»ΡŽΡ‡ ΠΈ список, Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΡƒΠ΅Ρ‚ список Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎ ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‰ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡ΠΈ, ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΏΠ°Ρ€Ρƒ Β«ΠΊΠ»ΡŽΡ‡β€“Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅Β», Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Но Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Ρ‘Ρ‚, Ссли искомого ΠΊΠ»ΡŽΡ‡Π° Π½Π΅Ρ‚ Π² спискС? Π’ этом случаС ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Β«Π³ΠΎΠ»ΠΎΠ²ΡƒΒ» пустого списка, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ выполнСния. Однако слСдуСт ΡΡ‚Ρ€Π΅ΠΌΠΈΡ‚ΡŒΡΡ ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ наши ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π±Ρ‹Π»ΠΈ Π±ΠΎΠ»Π΅Π΅ устойчивыми ΠΊ «падСниям», поэтому Π΄Π°Π²Π°ΠΉΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ‚ΠΈΠΏ Maybe. Если ΠΌΡ‹ Π½Π΅ Π½Π°ΠΉΠ΄Ρ‘ΠΌ ΠΊΠ»ΡŽΡ‡Π°, Ρ‚ΠΎ Π²Π΅Ρ€Π½Ρ‘ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Nothing. Если Π½Π°ΠΉΠ΄Ρ‘ΠΌ, Π±ΡƒΠ΄Π΅ΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ Just <Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ нашли>.