Skip to content

Instantly share code, notes, and snippets.

@Shamrock-Frost
Created June 24, 2016 07:19
Show Gist options
  • Save Shamrock-Frost/5137ce9b151ddd77ec6ea74fb5b396c3 to your computer and use it in GitHub Desktop.
Save Shamrock-Frost/5137ce9b151ddd77ec6ea74fb5b396c3 to your computer and use it in GitHub Desktop.
Halle told me about an interview question at Microsoft, and I joked I'd solve it monoidally. I wasn't joking, Halle.
import Data.Monoid hiding (Sum)
class Monoid a => IntWrapper a where toInt :: a -> Int
newtype Sum = Sum Int deriving (Show, Eq)
instance IntWrapper Sum where toInt (Sum n) = n
instance Monoid Sum where
mempty = Sum 0
mappend (Sum a) (Sum b) = Sum (a + b)
newtype Prod = Prod Int deriving (Show, Eq)
instance IntWrapper Prod where toInt (Prod n) = n
instance Monoid Prod where
mempty = Prod 1
mappend (Prod a) (Prod b) = Prod $ repeatOp (Sum a) (Sum b)
newtype Exp = Exp Int deriving (Show, Eq)
instance IntWrapper Exp where toInt (Exp n) = n
instance Monoid Exp where
mempty = Exp 1
mappend (Exp a) (Exp b) = Exp $ repeatOp (Prod a) (Prod b)
newtype Tetr = Tetr Int deriving (Show, Eq)
instance IntWrapper Tetr where toInt (Tetr n) = n
instance Monoid Tetr where
mempty = Tetr 1
mappend (Tetr a) (Tetr b) = Tetr $ repeatOp (Exp a) (Exp b)
repeatOp :: IntWrapper m => m -> m -> Int
repeatOp a b = toInt . mconcat $ replicate (toInt b) a
main = do
print $ (Sum 1) <> (Sum 3)
print $ (Prod 5) <> (Prod 7)
print $ (Exp 3) <> (Exp 5)
print $ (Tetr 2) <> (Tetr 4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment