Skip to content

Instantly share code, notes, and snippets.

@Solonarv
Created March 29, 2019 17:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Solonarv/6f5eefbb4dfdad8892f2440de1020d6a to your computer and use it in GitHub Desktop.
Save Solonarv/6f5eefbb4dfdad8892f2440de1020d6a to your computer and use it in GitHub Desktop.
Should be correct, but takes so long to compile that I have no idea if it actually works.
{-# OPTIONS_GHC -Wno-unticked-promoted-constructors -freduction-depth=0 #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
import GHC.TypeLits
type m `Divides` n = (m `Mod` n) == 0
type family Range l h where
Range l h = If (l <=? h) (l : Range (l+1) h) '[]
type family (==) (x :: k) (y :: k) :: Bool where
x == x = True
_ == _ = False
type family If p thn els where
If True thn _ = thn
If False _ els = els
-------------------------------------------------------------------------------
type family FizzBuzzOnce (assocs :: [(Nat, Symbol)]) (n :: Nat) :: ErrorMessage where
FizzBuzzOnce '[] n = ShowType n
FizzBuzzOnce ('(m, sym):as) n = If (m `Divides` n) (FizzBuzzHelper as n (Text sym)) (FizzBuzzOnce as n)
type family FizzBuzzHelper (assocs :: [(Nat, Symbol)]) (n :: Nat) (acc :: ErrorMessage) :: ErrorMessage where
FizzBuzzHelper '[] _ acc = acc
FizzBuzzHelper ('(m, sym):as) n acc = FizzBuzzHelper as n (If (m `Divides` n) (Text sym :<>: acc) acc)
type family FizzBuzzAll (assocs :: [(Nat, Symbol)]) (ns :: [Nat]) :: ErrorMessage where
FizzBuzzAll as '[] = Text "-- Done."
FizzBuzzAll as (n : ns) = FizzBuzzOnce as n :$$: FizzBuzzAll as ns
class FizzBuzzInst as ns where
doFizzBuzz :: forall xx. xx
doFizzBuzz = undefined
instance TypeError (FizzBuzzAll as ns) => FizzBuzzInst as ns
-------------------------------------------------------------------------------
main = doFizzBuzz @[(3, "Fizz"), (5, "Buzz")] @(Range 1 100)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment