Skip to content

Instantly share code, notes, and snippets.

@na-o-ys
Last active February 14, 2017 09:50
Show Gist options
  • Select an option

  • Save na-o-ys/32109dd00e51900720d72c5c8149fd8c to your computer and use it in GitHub Desktop.

Select an option

Save na-o-ys/32109dd00e51900720d72c5c8149fd8c to your computer and use it in GitHub Desktop.
About covariance / contravariance in Haskell
{-# LANGUAGE ExistentialQuantification #-}
-- C1 :> C2 :> C3
class C1 a where
f1 :: a -> String
class (C1 a) => C2 a where
f2 :: a -> String
class (C2 a) => C3 a where
f3 :: a -> String
data D1 = D1 -- instance of C1
data D2 = D2 -- instance of C1 and C2
data D3 = D3 -- instance of C1 and C2 and C3
instance C1 D1 where
f1 d = "C1-D1"
instance C1 D2 where
f1 d = "C1-D2"
instance C1 D3 where
f1 d = "C1-D3"
instance C2 D2 where
f2 d = "C2-" ++ f1 d
instance C2 D3 where
f2 d = "C2-" ++ f1 d
instance C3 D3 where
f3 d = "C3-" ++ f2 d
data C2s = forall a . C2 a => MkC2s a
--
-- Covariance
--
funcC2 :: C2s -> String
funcC2 (MkC2s d) = f2 d
-- NG: result1 = funcC2 $ MkC2s D1
result2 = funcC2 $ MkC2s D2
result3 = funcC2 $ MkC2s D3
--
-- Contravariance
--
higherFuncC2 :: (C2s -> String) -> String
higherFuncC2 f = f $ MkC2s D3
higher1 = higherFuncC2 $ \(MkC2s d) -> f1 d
higher2 = higherFuncC2 $ \(MkC2s d) -> f2 d
-- NG: higher3 = higherFuncC2 $ \(MkC2s d) -> f3 d
main = putStrLn "ok"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment