content: 
  {-# LANGUAGE TypeFamilies #-}
  
  module Cc015 where
  
  import Foreign
  import Foreign.C.Types
  
  type S a = a
  type IOS a = IO a
  type SFunPtr a = FunPtr a
  
  type family F a
  type instance F Int = Int
  type instance F Bool = G2
  type instance F Char = FunPtr (Int -> IO Int)
  
  newtype G1  = G1  Int
  newtype G1F = G1F (F (S Int))
  newtype G2  = G2  Char
  newtype G3  = G3  (IO Int)
  newtype G4  = G4  G3
  newtype NIO a = NIO (IO a)
  
  -- Type synonyms should be transparent to the typechecker
  foreign import ccall f1       ::          S Int -> IOS Int
  foreign export ccall "g1"  f1 ::          S Int -> IOS Int
  foreign import ccall "&h1" h1 :: SFunPtr (S Int -> IOS Int)
  -- As should type functions
  foreign import ccall f2         ::         F Int -> IO (F Int)
  foreign export ccall "g2"   f2  ::         F Int -> IO (F Int)
  foreign import ccall "&h2"  h2  :: F Char
  foreign import ccall "&h2b" h2b :: FunPtr (F Int -> IO (F Int))
  -- And newtype
  foreign import ccall f3       ::         G1 -> G2 -> G4
  foreign export ccall "g3" f3  ::         G1 -> G2 -> G4
  foreign import ccall "&h3" h3 :: FunPtr (G1 -> G2 -> G4)
  -- And a combination
  foreign import ccall f4       ::         G1F -> F Bool -> S G4
  foreign export ccall "g4" f4  ::         G1F -> F Bool -> S G4
  foreign import ccall "&h4" h4 :: FunPtr (G1F -> F Bool -> S G4)
  -- And a newtyped IO
  foreign import ccall f5       ::         NIO Int
  foreign export ccall "g5" f5  ::         NIO Int
  foreign import ccall "&h5" h5 :: FunPtr (NIO Int)
  
  