phi16
phi16

Reputation: 123

type-class difficult inference

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

Answers (1)

max taldykin
max taldykin

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

Related Questions