{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeInType #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE PolyKinds #-} module Clr.MarshalF where import Clr.Marshal import Data.Kind import GHC.TypeLits class MarshalF (n::Nat) (from::Type) (to::Type) where marshalF :: from -> to instance (Unmarshal x y) => MarshalF 0 x (IO y) where marshalF = unmarshal instance ( Marshal y0 x0 , Unmarshal xr yr ) => MarshalF 1 (x0 -> xr) (y0 -> IO yr) where marshalF f y0 = marshal y0 (unmarshal . f) instance ( Marshal y0 x0 , Marshal y1 x1 , Unmarshal xr yr ) => MarshalF 2 (x0 -> x1 -> xr) (y0 -> y1 -> IO yr) where marshalF f y0 y1 = marshal y0 (\x0-> marshal y1 (unmarshal . f x0)) instance ( Marshal y0 x0 , Marshal y1 x1 , Marshal y2 x2 , Unmarshal xr yr ) => MarshalF 3 (x0 -> x1 -> x2 -> xr) (y0 -> y1 -> y2 -> IO yr) where marshalF f y0 y1 y2 = marshal y0 $ \x0-> marshal y1 $ \x1 -> marshal y2 (unmarshal . f x0 x1) instance ( Marshal y0 x0 , Marshal y1 x1 , Marshal y2 x2 , Marshal y3 x3 , Unmarshal xr yr ) => MarshalF 4 (x0 -> x1 -> x2 -> x3 -> xr) (y0 -> y1 -> y2 -> y3 -> IO yr) where marshalF f y0 y1 y2 y3 = marshal y0 $ \x0-> marshal y1 $ \x1 -> marshal y2 $ \x2 -> marshal y3 (unmarshal . f x0 x1 x2) instance ( Marshal y0 x0 , Marshal y1 x1 , Marshal y2 x2 , Marshal y3 x3 , Marshal y4 x4 , Unmarshal xr yr ) => MarshalF 5 (x0 -> x1 -> x2 -> x3 -> x4 -> xr) (y0 -> y1 -> y2 -> y3 -> y4 -> IO yr) where marshalF f y0 y1 y2 y3 y4 = marshal y0 $ \x0-> marshal y1 $ \x1 -> marshal y2 $ \x2 -> marshal y3 $ \x3 -> marshal y4 (unmarshal . f x0 x1 x2 x3)