Skip to content

Instantly share code, notes, and snippets.

@david-christiansen
Last active August 29, 2015 14:04
Show Gist options
  • Select an option

  • Save david-christiansen/b0035b232febab542cd2 to your computer and use it in GitHub Desktop.

Select an option

Save david-christiansen/b0035b232febab542cd2 to your computer and use it in GitHub Desktop.
Dependently typed FizzBuzz, about 5 years late to the party
module FizzBuzz
data FB : Nat -> Type where
N : (n : Nat) -> {auto not3 : Not (n `mod` 3 = 0)} -> {auto not5 : Not (n `mod` 5 = 0)} -> FB n
Fizz : (n : Nat) -> {auto div3 : n `mod` 3 = 0} -> {auto not4 : Not (n `mod` 5 = 0)} -> FB n
Buzz : (n : Nat) -> {auto not3 : Not (n `mod` 3 = 0)} -> {auto div5 : n `mod` 5 = 0} -> FB n
FizzBuzz : (n : Nat) -> {auto div3 : n `mod` 3 = 0} -> {auto div5 : n `mod` 5 = 0} -> FB n
fb : (n : Nat) -> FB n
fb n with (decEq (n `mod` 3) 0)
fb n | (Yes prf) with (decEq (n `mod` 5) 0)
fb n | (Yes prf) | (Yes x) = FizzBuzz n
fb n | (Yes prf) | (No contra) = Fizz n
fb n | (No contra) with (decEq (n `mod` 5) 0)
fb n | (No contra) | (Yes prf) = Buzz n
fb n | (No contra) | (No f) = N n
nats : Stream Nat
nats = iterate S Z
fizzBuzz : Stream (n : Nat ** FB n)
fizzBuzz = map (\n => (n ** (fb n))) (tail nats)
instance Show (n : Nat ** FB n) where
show (x ** N x) = show x
show (x ** Fizz x) = "Fizz"
show (x ** Buzz x) = "Buzz"
show (x ** FizzBuzz x) = "FizzBuzz"
namespace Main
main : IO ()
main = sequence_ . map (putStrLn . show) . take 100 $ fizzBuzz
@LeifW
Copy link

LeifW commented Jan 22, 2015

Could also write [1..] to get a Stream of Nats.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment