Last active
March 22, 2021 19:51
-
-
Save guibou/0e2d5597500a12c3579365e594a4079b to your computer and use it in GitHub Desktop.
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 FlexibleContexts #-} | |
| {-# LANGUAGE TypeFamilies #-} | |
| {-# LANGUAGE FunctionalDependencies #-} | |
| {-# LANGUAGE MultiParamTypeClasses #-} | |
| {-# LANGUAGE UndecidableInstances #-} | |
| {-# LANGUAGE FlexibleInstances #-} | |
| import GHC.Float | |
| class RealToFrac a where | |
| convert :: a -> Double | |
| instance {-# OVERLAPPABLE #-} Real t => RealToFrac t where convert = realToFrac | |
| instance RealToFrac Double where convert = id | |
| instance RealToFrac Float where convert = float2Double | |
| -- Version without the fundep | |
| class RealToFrac' a b where | |
| convert' :: a -> b | |
| instance {-# OVERLAPPABLE #-} Real t => RealToFrac' t Double where convert' = realToFrac | |
| instance RealToFrac' Double Double where convert' = id | |
| instance RealToFrac' Float Float where convert' = id | |
| -- Here GHC is not able to deduce b | |
| -- chien :: (Show b, RealToFrac' a b) => a -> String | |
| -- chien = show . convert' | |
| -- That's why I want a fundep | |
| class RealToFrac'' a b | a -> b where | |
| convert'' :: a -> b | |
| -- this instance is impossible because it conflicts with fundeps | |
| -- instance {-# OVERLAPPABLE #-} Real t => RealToFrac'' t Double where convert'' = realToFrac | |
| instance RealToFrac'' Double Double where convert'' = id | |
| instance RealToFrac'' Float Float where convert'' = id | |
| -- Here GHC is able to deduce b | |
| chien' :: (Show b, RealToFrac'' a b) => a -> String | |
| chien' = show . convert'' | |
| -- Solution with closed type family | |
| type family ToRealFracT t where | |
| ToRealFracT Double = Double | |
| ToRealFracT Float = Float | |
| ToRealFracT t = Double | |
| -- | |
| -- | |
| class RealToFrac''' a where | |
| convert''' :: a -> ToRealFracT a | |
| instance {-# OVERLAPPABLE #-} (ToRealFracT t ~ Double, Real t) => RealToFrac''' t where convert''' = realToFrac | |
| instance RealToFrac''' Double where convert''' = id | |
| instance RealToFrac''' Float where convert''' = id | |
| -- Here GHC is able to deduce b | |
| chien'' :: (Show (ToRealFracT a), RealToFrac''' a) => a -> String | |
| chien'' = show . convert''' | |
| -- Solution with open type family | |
| type family ToRealFracTOpen t | |
| type instance ToRealFracTOpen Double = Double | |
| type instance ToRealFracTOpen Float = Float | |
| -- This one is not possible | |
| -- type instance ToRealFracTOpen t = Double | |
| -- | |
| -- | |
| class RealToFrac'''' a where | |
| convert'''' :: a -> ToRealFracTOpen a | |
| -- this instance is impossible because it conflicts with fundeps | |
| instance {-# OVERLAPPABLE #-} (ToRealFracTOpen t ~ Double, Real t) => RealToFrac'''' t where convert'''' = realToFrac | |
| instance RealToFrac'''' Double where convert'''' = id | |
| instance RealToFrac'''' Float where convert'''' = id | |
| -- Here GHC is able to deduce b | |
| chien''' :: (Show (ToRealFracTOpen a), RealToFrac'''' a) => a -> String | |
| chien''' = show . convert'''' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment