callmekohei's blog

callmekoheiのひとりごと

なんとなく FizzBuzz かいてみた

なんかハイボール片手にツイッターをぼけ〜っとみてたら

FizzBuzzしたくなったのでかいてみた!

こんな感じ

コード

fizzbuzz.fsx

#load "./interaction.fsx"
open callmekohei.Interaction

let (|Div|_|) by n = if n % by = 0 then Some Div else None

let fizzbuzz = function
    | Div 15 -> "FizzBuzz"
    | Div  5 -> "Buzz"
    | Div  3 -> "Fizz"
    | n      -> string n

let rec main s =
    match s with
    | "init" -> stdout.WriteLine("--- start ---")
                main ( stdin.ReadLine() )
    | "quit" -> printer.Quit()
    | _ when fst (System.Int32.TryParse(s)) = false -> 
        stdout.WriteLine("数字を入力してください!")
        main ( stdin.ReadLine() )
    | _      -> printer.WriteLine(fizzbuzz(int s))
                main ( stdin.ReadLine() )

main "init"

interaction.fsx

namespace callmekohei
module Interaction =

    type PrinterAgent() =
        let inbox = MailboxProcessor.Start( fun inbox ->
            let rec loop () = async {
                let! ( msg : Choice< string , AsyncReplyChannel<unit> > ) = inbox.Receive()
                match msg with
                | Choice1Of2 (s:string) ->
                    stdout.WriteLine(s)
                    return! loop ()
                | Choice2Of2 (ch : AsyncReplyChannel<unit>) -> ch.Reply ()
            }
            loop ()
        )

        member x.WriteLine(s) = inbox.Post ( Choice1Of2 s )
        member x.Quit()       = inbox.PostAndReply(fun ch -> Choice2Of2 ch)

    let printer = PrinterAgent()

みどころ〜

アクティブパターンなところ

数字かどうか判定〜

mailboxporcessorをつかってるところ〜(マルチスレッドでも安全!)