Haskell
チラシの裏

Haskell学習時に書いたコード置き場

いいコードが書けるようになったら随時書き直す。


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 -1Non-exhaustive patterns in functionとなるが、fizzBuzz 0Fizz 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

感服したコード。自分では思いつけなかった。

【解答例】Haskell 超入門

reverse' xs = f xs []

where
f [] ys = ys
f (x:xs) ys = f xs (x:ys)