Real World Haskell - 第4章 Part3 How to think about loops

Real World HaskellHaskell を継続的に勉強中。


Chapter 4. Functional programming
Chapter 4. Functional programming

How to think about loops

  • for/while ループは Haskell には存在しないので別の方法で表現する必要がある
Explicit recursion
import Data.Char (digitToInt) -- we'll need ord shortly

asInt :: String -> Int
loop :: Int -> String -> Int

asInt xs = loop 0 xs
loop acc [] = acc
loop acc (x:xs) = let acc' = acc * 10 + digitToInt x
                  in loop acc' xs
  • 変数名のシングルクォートはイディオム ("prime" と読む)
  • structural recursion もイディオム
    • the base case / terminationg case
    • the recursive case / inductive case
  • tail recursion では TCO (Tail Call Optimisation) が行われているので constant space で動作する
Transforming every piece of input
square :: [Double] -> [Double]

square (x:xs) = x*x : square xs
square []     = []
import Data.Char (toUpper)

upperCase :: String -> String

upperCase (x:xs) = toUpper x : upperCase xs
upperCase []     = []
Mapping over a list

先の例を高階関数 (higher-order function) で書いてみる

ghci> :type map
map :: (a -> b) -> [a] -> [b]
square2 xs = map squareOne xs
    where squareOne x = x * x

upperCase2 xs = map toUpper xs
myMap :: (a -> b) -> [a] -> [b]

myMap f (x:xs) = f x : myMap f xs
myMap _ _      = []