PureScriptで簡単FizzBuzz


はじめに

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を送ってください😎