Advertisement
Guest User

Untitled

a guest
Oct 21st, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.79 KB | None | 0 0
  1. {-# LANGUAGE DataKinds #-}
  2. {-# LANGUAGE FlexibleContexts #-}
  3. {-# LANGUAGE FlexibleInstances #-}
  4. {-# LANGUAGE TypeFamilies #-}
  5. {-# LANGUAGE TypeOperators #-}
  6.  
  7.  
  8. import Data.Proxy
  9. import GHC.TypeLits
  10.  
  11.  
  12. -- we use DataKinds to lift FizzBuzzItems to the type system level
  13.  
  14. data FizzBuzzItem = Number Nat
  15. | Fizz
  16. | Buzz
  17. | FizzBuzz
  18.  
  19.  
  20. -- the result family associates the four possible boolean conditions to a resulting item
  21.  
  22. type family FizzBuzzResult (d3 :: Bool) (d5 :: Bool) (n :: Nat) where
  23. FizzBuzzResult 'False 'False n = 'Number n
  24. FizzBuzzResult 'True 'False n = 'Fizz
  25. FizzBuzzResult 'False 'True n = 'Buzz
  26. FizzBuzzResult 'True 'True n = 'FizzBuzz
  27.  
  28.  
  29. -- GetFizzBuzz is simply a type-level function from type-level number to item
  30. -- you can call it in GHCI with:
  31. -- :t (Proxy :: Proxy (GetFizzBuzz 15))
  32.  
  33. type GetFizzBuzz (n :: Nat) = FizzBuzzResult (Mod n 3 <=? 0) (Mod n 5 <=? 0) n
  34.  
  35.  
  36. -- to go further: let's have a runtime value!
  37. -- we add overlapping instances for proxies of our type-level items
  38.  
  39. instance {-# OVERLAPPING #-} Show (Proxy 'Fizz) where show = const "Fizz"
  40. instance {-# OVERLAPPING #-} Show (Proxy 'Buzz) where show = const "Buzz"
  41. instance {-# OVERLAPPING #-} Show (Proxy 'FizzBuzz) where show = const "FizzBuzz"
  42.  
  43. instance {-# OVERLAPPING #-} KnownNat n => Show (Proxy ('Number n)) where
  44. show = show . natVal . toNatProxy
  45. where toNatProxy :: Proxy ('Number n) -> Proxy n
  46. toNatProxy = const Proxy
  47.  
  48.  
  49. -- and we introduce a function that does the string output
  50. -- you can call it in GHCI with
  51. -- fb (Proxy :: Proxy 12)
  52.  
  53. fb :: Show (Proxy (GetFizzBuzz n)) => Proxy (n :: Nat) -> String
  54. fb = show . toResult
  55. where toResult :: Proxy (n :: Nat) -> Proxy (GetFizzBuzz n)
  56. toResult = const Proxy
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement