-- http://www.codewars.com/kata/543cb1d8f6b726292d0000d7
module Phalanx where

import Data.Monoid
import Data.String
import Data.Maybe

type Name = String

data Phalanx
  = Literal String
  | Empty
  | Join Phalanx Phalanx
  | Repeat Int Phalanx
  | Lookup Name

instance IsString Phalanx where
  fromString = Literal

instance Monoid Phalanx where
  mempty = Empty
  mappend = Join

rep :: Int -> Phalanx -> Phalanx
rep = Repeat

l :: Name -> Phalanx
l = Lookup

interp :: (Name -> Maybe String) -> (Phalanx -> Maybe String)
interp dict ph = f ph where
  f Empty = Nothing
  f (Literal x) = Just x
  f (Join x y) = if f x /= Nothing && f y /= Nothing then f x <> f y else Nothing
  f (Repeat n x) = mconcat $ replicate n (f x)
  f (Lookup x) = dict x