Reputation: 123
I want to make following type inferable :
class Lit a
instance Lit Int
instance Lit Float
class App a b
instance App Float b
f :: (Lit a, App a b) => a -> b -- a should be Float
I know this sample cannot be inferred a
to Float
because type class be not closed, at least.
What should I do to achieve the purpose?
Additionally, the thing I want to do is constructing Typed EDSL using TH and Haskell Type Checker. for example if the variable (Int or Float) "p" are multiplied by Float, I want to infer "p" to Float. So the solution to this is also welcomed.
Upvotes: 1
Views: 107
Reputation: 12908
It is not very clear what problem you are trying to solve with this code, but as @chi stated, you can try FunDeps
{-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}
class Lit a
instance Lit Int
instance Lit Float
class App a b | b -> a
instance App Float b
f :: (Lit a, App a b) => a -> Maybe b
f x = Nothing
or TypeFamilies
{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
class Lit a
instance Lit Int
instance Lit Float
class App res where
type Arg res
instance App res where
type Arg res = Float
f :: App b => Arg b -> Maybe b
f x = Nothing
Using FunDeps in this example is more concise, but in my experience TypeFamilies + GADTs solutions are more straightforward and manageable for type-level programming.
Upvotes: 2