Arantium Maestum

プログラミング、囲碁、読書の話題

Thinking Functionally with Haskell勉強メモ: 第1章問題

Exercise A

右辺と左辺の等価性の「証明」

sum . map double = double .sum

分配法則 (distributative property)でc*a + c*b = c * (a + b)

sum . map sum = sum . concat

結合法則 (associative property)で(a+b)+(c+d) = (a+b+c+d)

sum . sort = sort

交換法則 (commutative property)でa+d+c+b = a+b+c+d

Exercise D

words . map toLowerが文字列を小文字化してから単語に分割する処理。

map (map toLower) . wordsが文字列を単語に分割してから、各単語を小文字化する処理。

Exercise E

0, [], idが和、リスト結合、関数合成の単位元(identity element)

Exercise F

整数nと単語リストwordListを受け取り、wordListの中のn文字の単語のアナグラムを列挙する文字列を出力する関数anagramsを大まかに定義する。

トップレベルの処理としては

anagrams :: Int -> [Word] -> String
anagrams n = combineEntries . map showAnagramEntries . takeWordsOfLength n

個々の関数の型は:

takeWordsOfLength :: Int -> [Word] -> [Word]
showAnagramEntries :: Word -> String
combineEntries :: [String] -> String

最初の関数を少し詰めると:

takeWordsOfLength n = filter (isWordOfLength n)
isWordOfLength :: Int -> Word -> Bool

という感じか。

Exercise G

(0<n<10)人の男が芝を刈りに行く歌を出力する関数songを定義する。

song :: Int -> String
song 0 = ""
song 1 = verse 1
song n  = song (n-1) ++ "\n" ++ verse n
verse n = line1 n ++ line2 n ++ line3 n ++ line4 n

verse :: Int -> String
line1 :: Int -> String
line2 :: Int -> String
line3 :: Int -> String
line4 :: Int -> String

line1 = capitalize . line1a
line1a 0 = ""
line1a 1 = "one man went to mow\n"
line1a n = wordify n ++ " men went to mow\n"

line2 n = "Went to mow a meadow\n"

line3 = capitalize . line3a
line3a 0 = ""
line3a 1 = "one man and his dog\n"
line3a n = wordify n ++ " men, " ++ line3a (n-1) 

line4 = line2

capitalize :: String -> String
capitalize (c:cs) = toUpper c : cs

wordify :: Int -> String
wordify n = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"] !! n

こんな感じか?

putStrLn (song 5)の出力:

One man went to mow
Went to mow a meadow
One man and his dog
Went to mow a meadow

Two men went to mow
Went to mow a meadow
Two men, one man and his dog
Went to mow a meadow

Three men went to mow
Went to mow a meadow
Three men, two men, one man and his dog
Went to mow a meadow

Four men went to mow
Went to mow a meadow
Four men, three men, two men, one man and his dog
Went to mow a meadow

Five men went to mow
Went to mow a meadow
Five men, four men, three men, two men, one man and his dog
Went to mow a meadow