はじめに
PureScriptのFizzBuzzを様々な方法で書いてみました。
例1
module Main where
import Prelude
import Data.Array ((..))
import Effect (Effect, foreachE)
import Effect.Console (log)
main :: Effect Unit
main = foreachE (fbList 100) log
fbList :: Int -> Array String
fbList n = map judge $ 1 .. n
judge :: Int -> String
judge n
| n `mod` 15 == 0 = "Fizz-Buzz"
| n `mod` 5 == 0 = "Buzz"
| n `mod` 3 == 0 = "Fizz"
| otherwise = show n
直感的に読めます。
例2
module Main where
import Prelude
import Control.Alt ((<|>))
import Data.Array (mapMaybe, (..))
import Data.Maybe (Maybe(..))
import Effect (Effect, foreachE)
import Effect.Console (log)
main :: Effect Unit
main = foreachE (fbList 100) log
fbList :: Int -> Array String
fbList n = mapMaybe judge $ 1 .. n
judge :: Int -> Maybe String
judge n = fizzbuzz n <|> buzz n <|> fizz n <|> Just (show n)
fizzbuzz :: Int -> Maybe String
fizzbuzz n = if n `mod` 15 == 0 then Just "Fizz-Buzz" else Nothing
buzz :: Int -> Maybe String
buzz n = if n `mod` 5 == 0 then Just "Buzz" else Nothing
fizz :: Int -> Maybe String
fizz n = if n `mod` 3 == 0 then Just "Fizz" else Nothing
judge関数にある「A <|> B <|> C」は「Aが空ならB、Bが空ならC」のように読みます。fizzbuzzでもbuzzでもfizzでもないならそのまま数字を出します。
If式は関数型言語を使ったことがない人にも読みやすいと思います。
例3
module Main where
import Prelude
import Control.Alt ((<|>))
import Data.Array ((..))
import Data.Foldable (for_)
import Data.Maybe (Maybe(..), fromMaybe)
import Effect (Effect)
import Effect.Console (log)
main :: Effect Unit
main = for_ (from .. to) $ log <<< judge
where
from = 1
to = 100
judge :: Int -> String
judge n = fromMaybe (show n) $ fizzbuzz n <|> buzz n <|> fizz n
fizzbuzz :: Int -> Maybe String
fizzbuzz n = if n `mod` 15 == 0 then Just "Fizz-Buzz" else Nothing
buzz :: Int -> Maybe String
buzz n = if n `mod` 5 == 0 then Just "Buzz" else Nothing
fizz :: Int -> Maybe String
fizz n = if n `mod` 3 == 0 then Just "Fizz" else Nothing
forループのようなものが使えます。
fromMaybeはデフォルト値を設定することができます。fizzbuzz、buzz、fizzのどれでもなかった場合はnを文字列にして返します。
例4
module Main where
import Prelude hiding (min, max)
import Control.Alt ((<|>))
import Data.Maybe (Maybe(..), fromMaybe)
import Effect (Effect)
import Effect.Console (log)
main :: Effect Unit
main = loop 1
loop :: Int -> Effect Unit
loop n
| n <= min = log "It cannot be negative or 0."
| n > max = log "It cannot be bigger than 100."
| n == max = log (judge n)
| otherwise = log (judge n) *> loop (n + 1)
min :: Int
min = 0
max :: Int
max = 100
judge :: Int -> String
judge n = fromMaybe (show n) $ fizzbuzz n <|> buzz n <|> fizz n
fizzbuzz :: Int -> Maybe String
fizzbuzz n = if n `mod` 15 == 0 then Just "Fizz-Buzz" else Nothing
buzz :: Int -> Maybe String
buzz n = if n `mod` 5 == 0 then Just "Buzz" else Nothing
fizz :: Int -> Maybe String
fizz n = if n `mod` 3 == 0 then Just "Fizz" else Nothing
loop関数の再帰によってループを作っています。
まとめ
いろんな書き方ができて、読みやすくて、とてもいい言語です🙂
他の書き方や指摘などがあれば、ぜひコメントやEdit Requestを送ってください😎