練習問題(つづき)

「入門Haskell」のp.31から二つ目。

② 単語のカウント方法として,`Theory of Everything’のようにバッククォートとシングルクォートで囲まれたパートを,1つの単語として表現するように wordsCount を拡張しなさい。

オリジナルの wordsCount。

wordsCount str = outWords str
    where outWords [] = 0
          outWords (c:cs)
              | isAlphaNum c = 1 + inWords cs
              | otherwise = outWords cs
          inWords [] = 0
          inWords (c:cs)
              | isAlphaNum c = inWords cs
              | otherwise = outWords cs

拡張版。

wordsCount str = outWords str
    where outWords [] = 0
          outWords (c:cs)
              | c == '`' = 1 + inQuote cs
              | isAlphaNum c = 1 + inWords cs
              | otherwise = outWords cs
          inWords [] = 0
          inWords (c:cs)
              | c == '`' = 1 + inQuote cs
              | isAlphaNum c = inWords cs
              | otherwise = outWords cs
          inQuote [] = 0
          inQuote (c:cs)
              | c == '\'' = outWords cs
              | otherwise = inQuote cs

結果。

*Main> wordsCount "`Theory of Everything' by Greg Egan"
4

練習問題

「入門Haskell」のp.31から。
まずは一つ目。linesCountの拡張

① linesCountでは,空白行が続く場合にどんどんカウントしてきます。これを空白行(何もない行)を無視するように拡張しなさい。

オリジナルのlinesCount。

linesCount [] = 0
linesCount ('\n':cs) = 1 + linesCount cs
linesCount (c:cs) = linesCount cs

結果。1st line,2nd line … は空行を無視した行番号で,1st line と2nd lineの間に空行がある。

*Main> linesCount "1st line\n\n2nd line\n3rd line\n"
4

で,拡張版。

linesCount lines = atHead lines
    where atHead []        = 0
          atHead ('\n':cs) = atHead cs
          atHead (c:cs)    = 1 + inLine cs
          inLine []        = 0
          inLine ('\n':cs) = atHead cs
          inLine (c:cs)    = inLine cs

結果。

*Main> linesCount "1st line\n\n2nd line\n3rd line\n"
3