{-# OPTIONS_HADDOCK hide #-} {-# LANGUAGE NoImplicitPrelude #-} module Imj.Graphics.Interpolation.SequentiallyInterpolatedList( SequentiallyInterpolatedList(..) ) where import Imj.Prelude import Data.List(length, mapAccumL) import Imj.Graphics.Class.DiscreteInterpolation import Imj.Util -- | A 'List'-like type to interpolate sequentially (one index at a time) between same-index elements. newtype SequentiallyInterpolatedList a = SequentiallyInterpolatedList [a] deriving(Eq, Ord, Show) -- | Interpolation between 2 'SequentiallyInterpolatedList', occuring sequentially -- i.e interpolating between one pair of same-index elements at a time, starting with -- 0 index and increasing. -- Prerequisite : lists have the same lengths. instance (DiscreteDistance a) => DiscreteDistance (SequentiallyInterpolatedList a) where distance (SequentiallyInterpolatedList l) (SequentiallyInterpolatedList l') = succ $ sum $ zipWith (\x y -> pred $ distance x y) l (assert (length l' == length l) l') -- | Interpolation between 2 'SequentiallyInterpolatedList', occuring sequentially -- i.e interpolating between one pair of same-index elements at a time, starting with -- 0 index and increasing. -- Prerequisite : lists have the same lengths. instance (DiscreteInterpolation a) => DiscreteInterpolation (SequentiallyInterpolatedList a) where interpolate (SequentiallyInterpolatedList l) (SequentiallyInterpolatedList l') progress = SequentiallyInterpolatedList $ snd $ mapAccumL (\acc (e,e') -> let d = pred $ distance e e' r = interpolate e e' $ clamp acc 0 d in (acc-d, r)) progress $ zip l (assert (length l' == length l) l')