{-# LANGUAGE TypeFamilies, ConstraintKinds #-} module Foo( shared, foo, bar) where -- module Foo where import Data.Kind {- foo :: [Int] -> [Int] foo = let f = map negate in f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f . f . f . f . f . f . f . f . f . f . f . f . f -} type family Domain (f :: Type -> Type) a :: Constraint type instance Domain [] a = () instance MyFunctor [] where myfmap = map class MyFunctor f where myfmap :: (Domain f a, Domain f b) => (a -> b) -> f a -> f b shared :: (MyFunctor f, Domain f Int) => f Int -> f Int shared = let f = myfmap negate in f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f. f . f . f . f . f . f . f . f . f . f . f . f . f foo xs = shared $ 0:xs bar xs = 0:shared xs