Created
September 13, 2016 14:25
-
-
Save gallais/3b7c7d9488b25978caa278bc18617f79 to your computer and use it in GitHub Desktop.
Instance disambiguation using a type family
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE UndecidableInstances #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE TypeOperators #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
{-# LANGUAGE PolyKinds #-} | |
module Provider2 where | |
import Data.Proxy | |
import Data.Type.Equality | |
data Location = IsLeft | IsRight | IsNone | |
class Provider a b (f :: Location) where | |
getInstance' :: Proxy f -> a -> b | |
type family If (b :: Bool) (l :: k) (r :: k) :: k where | |
If 'True l r = l | |
If 'False l r = r | |
type family Inspect t x :: Location where | |
Inspect (l, r) x = If (x == l) IsLeft (If (x == r) IsRight IsNone) | |
instance Provider r x (Inspect r x) => Provider (l, r) x 'IsNone where | |
getInstance' _ (l, r) = getInstance' (Proxy :: Proxy (Inspect r x)) r | |
instance Provider (l, r) l 'IsLeft where | |
getInstance' _ (l, _) = l | |
instance Provider (l, r) r 'IsRight where | |
getInstance' _ (_, r) = r | |
getInstance :: forall t x. Provider t x (Inspect t x) => t -> x | |
getInstance = getInstance' (Proxy :: Proxy (Inspect t x)) | |
tryFunc1 :: Int | |
tryFunc1 = | |
let provider = ("test", (10, ())) :: (String, (Int, ())) | |
in getInstance provider | |
tryFunc2 :: String | |
tryFunc2 = | |
let provider = ("test", (10, ())) :: (String, (Int, ())) | |
in getInstance provider | |
tryFunc3 :: Int | |
tryFunc3 = | |
let provider = ("test", ((), 10)) :: (String, ((), Int)) | |
in getInstance provider |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment