いいコードが書けるようになったら随時書き直す。
FizzBuzz
FizzBuzz.hs
fizzBuzz :: Integer -> String
fizzBuzz n
| n <= 0 = show n
| mod n 15 == 0 = "Fizz Buzz"
| mod n 5 == 0 = "Buzz"
| mod n 3 == 0 = "Fizz"
| otherwise = show n
本来n <= 0
はFizzBuzz関数の入力として相応しくないので、未定義とすべきか。Java等にある例外(Exception)的なものはHaskellにあるのだろうか。
下のコードだとfizzBuzz -1
はNon-exhaustive patterns in function
となるが、fizzBuzz 0
はFizz Buzz
となってしまう。
すべての条件にn > 0
をANDでつけるのはイマイチ..
FizzBuzz.hs
fizzBuzz :: Integer -> String
fizzBuzz n
| mod n 15 == 0 = "Fizz Buzz"
| mod n 5 == 0 = "Buzz"
| mod n 3 == 0 = "Fizz"
| n >= 1 = show n
関数を一つ挟めば実現できるが、もうちょっとスマートに書きたい。
ローカルで使う関数はwhere句の中で定義する。
FizzBuzz.hs
fizzBuzz :: Integer -> String
fizzBuzz n | n >= 1 = f n
where
f n
| mod n 15 == 0 = "Fizz Buzz"
| mod n 5 == 0 = "Buzz"
| mod n 3 == 0 = "Fizz"
| otherwise = show n
後で理解できるようになりたいコード
Haskellで書かれたおもしろいFizzBuzz ― Haskellで読めないコードに遭遇した時に解読する方法を徹底解説!
import Control.Monad (guard)
import Data.Maybe (fromMaybe)
import Data.Monoid ((<>))
main :: IO()
main = mapM_ (putStrLn . fizzbuzz) [1..100]
fizzbuzz :: Integer -> String
fizzbuzz = let (d ~> s) n = s <$ guard (n `mod` d == 0)
in fromMaybe . show <*> 3 ~> "Fizz" <> 5 ~> "Buzz"
Fibonacci
Fibonacci.hs
fibonacci :: Integer -> Integer
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n = fibonacci (n - 1) + fibonacci (n - 2)
後で理解できるようになりたいコード
Haskellでフィボナッチ数列 〜Haskellで非実用的なコードを書いて悦に入るのはやめろ〜
reverse
感服したコード。自分では思いつけなかった。
reverse' xs = f xs []
where
f [] ys = ys
f (x:xs) ys = f xs (x:ys)