Skip to content

Instantly share code, notes, and snippets.

@i-am-tom
Last active June 26, 2023 16:35
Show Gist options
  • Save i-am-tom/034acf5eec02d9318d6b67a6316d6e98 to your computer and use it in GitHub Desktop.
Save i-am-tom/034acf5eec02d9318d6b67a6316d6e98 to your computer and use it in GitHub Desktop.
Arguably the fastest implementation of FizzBuzz ever written.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UnsaturatedTypeFamilies #-}
import GHC.TypeLits
import Prelude hiding (Functor, Semigroup)
type Main = (Fizz <> Buzz) <$> (0 `To` 100)
---
class Semigroup m where
type (x :: m) <> (y :: m) :: m
instance Semigroup a => Semigroup (Either e a) where
type 'Left x <> 'Left _ = 'Left x
type 'Right x <> 'Left _ = 'Right x
type 'Left _ <> 'Right y = 'Right y
type 'Right x <> 'Right y = 'Right (x <> y)
instance Semigroup Symbol where
type x <> y = AppendSymbol x y
instance Semigroup b => Semigroup (a ~> b) where
type x <> y = Both x y
type family Both (f :: a ~> b) (g :: a ~> b) (x :: a) :: b where
Both f g x = f x <> g x
class Functor m where
type (f :: a ~> b) <$> (x :: m a) :: m b
instance Functor (Either e) where
type f <$> 'Right x = 'Right (f x)
type _ <$> 'Left x = 'Left x
instance Functor [] where
type f <$> '[ ] = '[]
type f <$> (x ': xs) = f x ': f <$> xs
type family IfZero (p :: Nat) (t :: k) (f :: k) :: k where
IfZero 0 t _ = t
IfZero _ _ f = f
type family Fizz (x :: Nat) :: Either Nat Symbol where
Fizz x = IfZero (x `Mod` 3) ('Right "Fizz") ('Left x)
type family Buzz (x :: Nat) :: Either Nat Symbol where
Buzz x = IfZero (x `Mod` 5) ('Right "Buzz") ('Left x)
type family (x :: Nat) `To` (y :: Nat) :: [Nat] where
x `To` x = '[]
x `To` y = x ': (x + 1) `To` y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment