module Data.Wrapper where

import Control.Category

class Wrapper a where
    type Inner a
    wrap :: Inner a -> a
    unwrap :: a -> Inner a

inWrapper :: (Wrapper a, Wrapper b) => (Inner a -> Inner b) -> (a -> b)
inWrapper = (wrap .) . (. unwrap)

inWrapper2 :: (Wrapper a, Wrapper b, Wrapper c) =>
              (Inner a -> Inner b -> Inner c) -> (a -> b -> c)
inWrapper2 = (inWrapper .) . (. unwrap)

inWrapper3 :: (Wrapper a, Wrapper b, Wrapper c, Wrapper d) =>
              (Inner a -> Inner b -> Inner c -> Inner d) -> (a -> b -> c -> d)
inWrapper3 = (inWrapper2 .) . (. unwrap)

inWrapper4 :: (Wrapper a, Wrapper b, Wrapper c, Wrapper d, Wrapper e) =>
              (Inner a -> Inner b -> Inner c -> Inner d -> Inner e)
           -> (a -> b -> c -> d -> e)
inWrapper4 = (inWrapper3 .) . (. unwrap)

inWrapper5 :: (Wrapper a, Wrapper b, Wrapper c, Wrapper d, Wrapper e, Wrapper f)
           => (Inner a -> Inner b -> Inner c -> Inner d -> Inner e -> Inner f)
           -> (a -> b -> c -> d -> e -> f)
inWrapper5 = (inWrapper4 .) . (. unwrap)
