2015-12-21 54 views
1

我要让以下类型推断出来:型一流难以推断

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 

我知道这个样品无法推断aFloat因为类型的类可以不是封闭的,至少。

我该怎么做才能达到目的?

此外,我想要做的事情是使用TH和Haskell类型检查器构造Typed EDSL。例如如果变量(Int或Float)“p”乘以Float,我想推断“p”为Float。所以这个解决方案也是受欢迎的。

+1

如前所述,由于您提到的原因,它是无法解决的:typeclasses是开放的。您可以尝试使用功能依赖关系或键入系列,如果这些可以使您自己的目标成为可能的话。 – chi

+0

这是正确的,我尝试了一些不同的代码风格,但任何尝试都没有成功......我想知道这可以使用封闭类型的家庭来解决,但我不知道该怎么做。 – phi16

+0

封闭式家庭是不够的,你也需要内射型家庭,这些家庭即将到来(tm)。 – sclv

回答

1

这是不是很清楚你试图用这个代码来解决什么问题,但作为@chi说,你可以尝试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 

或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 

使用这个FunDeps示例更简洁,但根据我的经验,TypeFamilies + GADTs解决方案对于类型级编程更直接且易于管理。

+0

对不起,在我的情况下,就像是一个'实例App Double b' ...我重新考虑了这个问题,并得出结论我的问题无法解决,所以我决定明确写出类型。谢谢。 – phi16