music-score-1.7: src/Music/Score/Clef.hs
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
-------------------------------------------------------------------------------------
-- |
-- Copyright : (c) Hans Hoglund 2012-2014
--
-- License : BSD-style
--
-- Maintainer : hans@hanshoglund.se
-- Stability : experimental
-- Portability : non-portable (TF,GNTD)
--
-- Provides clefs.
--
-- /Warning/ Experimental module.
--
-------------------------------------------------------------------------------------
module Music.Score.Clef (
ClefT(..),
HasClef(..),
) where
import Control.Arrow
import Control.Lens hiding (transform, parts)
import Control.Monad.Plus
import Data.Foldable (Foldable)
import qualified Data.Foldable as F
import qualified Data.List as List
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe
import Data.Semigroup
import Data.Set (Set)
import qualified Data.Set as Set
import Data.String
import Data.Traversable (Traversable)
import qualified Data.Traversable as T
import Data.Typeable
import Data.Void
import Music.Score.Meta.Clef
import Music.Score.Part
import Music.Score.Ties
import Music.Score.Internal.Util
import Music.Time
-- Put the given clef in front of the note
newtype ClefT a = ClefT { getClefT :: (Option (Last Clef), a) }
deriving (Functor, Semigroup, Monoid)
-- | Unsafe: Do not use 'Wrapped' instances
instance Wrapped (ClefT a) where
type Unwrapped (ClefT a) = (Option (Last Clef), a)
_Wrapped' = iso getClefT ClefT
instance Rewrapped (ClefT a) (ClefT b)
instance Monad ClefT where
return x = ClefT (mempty, x)
(>>=) = error "No ClefT.(>>=)"
type instance Part (ClefT a) = Part a
type instance SetPart b (ClefT a) = ClefT (SetPart b a)
instance (HasParts a b) => HasParts (ClefT a) (ClefT b) where
parts = _Wrapped . parts
instance (HasPart a b) => HasPart (ClefT a) (ClefT b) where
part = _Wrapped . part
instance Transformable a => Transformable (ClefT a) where
transform s = over (_Wrapped . _2) $ transform s
instance Tiable a => Tiable (ClefT a) where
toTied (ClefT (clef,a)) = (ClefT (clef,b), ClefT (mempty,c)) where (b,c) = toTied a
class HasClef a where
applyClef :: Clef -> a -> a
instance HasClef (ClefT a) where
applyClef c (ClefT (_,a)) = ClefT (Option $ Just $ Last c,a)
instance HasClef a => HasClef (b,a) where
applyClef c = fmap (applyClef c)
instance (HasPart' a, HasClef a) => HasClef (Score a) where
applyClef c = id -- TODO
-- applyClef c = mapFirst (applyClef c) id