Created
October 3, 2019 00:17
-
-
Save nicuveo/ce19538aeaada2a7d355f1dcb8ebe626 to your computer and use it in GitHub Desktop.
Haskell type-level fizzbuzz, version 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE FunctionalDependencies #-} | |
{-# LANGUAGE UndecidableInstances #-} | |
-- no data kinds, pure type level | |
-- let's start by defining booleans and numbers | |
data True | |
data False | |
data PZ | |
data PS n | |
type P1 = PS PZ | |
type P2 = PS P1 | |
type P3 = PS P2 | |
type P4 = PS P3 | |
type P5 = PS P4 | |
type P6 = PS P5 | |
type P7 = PS P6 | |
type P8 = PS P7 | |
type P9 = PS P8 | |
type P10 = PS P9 | |
type P11 = PS P10 | |
type P12 = PS P11 | |
type P13 = PS P12 | |
type P14 = PS P13 | |
type P15 = PS P14 | |
type P16 = PS P15 | |
-- type level functions: can a peano number be divided by 3 or 5? | |
class D3 n b | n -> b | |
instance D3 PZ True | |
instance D3 P1 False | |
instance D3 P2 False | |
instance D3 n b => D3 (PS (PS (PS n))) b | |
class D5 n b | n -> b | |
instance D5 PZ True | |
instance D5 P1 False | |
instance D5 P2 False | |
instance D5 P3 False | |
instance D5 P4 False | |
instance D5 n b => D5 (PS (PS (PS (PS (PS n))))) b | |
-- three new possible types, for our fizzbuzz values | |
data Fizz | |
data Buzz | |
data FizzBuzz | |
-- simple type-level mapping between our boolean types to a type-level fizzbuzz value | |
class GetFizzBuzz n b3 b5 v | n b3 b5 -> v | |
instance GetFizzBuzz n False False n | |
instance GetFizzBuzz n False True Fizz | |
instance GetFizzBuzz n True False Buzz | |
instance GetFizzBuzz n True True FizzBuzz | |
-- convenience function | |
-- use it in GHCI: | |
-- :t fb (undefined :: P12) | |
class FB n v | n -> v where | |
fb :: n -> v | |
instance (D3 n b3, D5 n b5, GetFizzBuzz n b3 b5 v) => FB n v where | |
fb = undefined |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment