繁体   English   中英

我怎样才能向GHC证明(b~Foo)?

[英]How can I prove to GHC that (b ~ Foo)?

新问题

我不会假装我知道如何思考或谈论哈斯克尔。 在伪java-oo-jargon中:

我想要做的是有一个“实现”“接口”的“结构”。 该接口的一部分是一个返回实现另一个接口的对象的函数。

interface IFiz {}

interface IBuz {
    function IFiz getFiz() 
}

class Foo implements IFiz { ... }
class Bar implements IBuz {
    IFiz fiz = new Foo();
    function getFiz() {
        return fiz;
    }
}

我怎么能在Haskell中做到这一点? 我这样做的尝试如下所述。


老问题

我怎样才能向GHC证明(b~Foo)?

我对这个问题的理解:

Foo是类型类Fiz的一个实例。

我希望Bar成为类型Buz的一个实例。

但是,编译器无法在punk方法的实现中推断出(b~Foo)。 但还有什么呢? 我尝试使用不推荐的直接方式添加数据约束,以及使用GADT,但似乎都没有工作(我继续得到完全相同的错误。)

data Foo = Foo Int                                                                                                                                                                                                                           
data Bar = Bar Foo                                                                                                                                                                                                                           

class Fiz a where                                                                                                                                                                                                                            
    funk :: a -> a -- Not important, I just wanted to put something in Fiz                                                                                                                                                                                                                           

class Buz a where                                                                                                                                                                                                                            
    punk :: Fiz b => a -> b                                                                                                                                                                                                                  

instance Fiz Foo where                                                                                                                                                                                                                       
    funk a = a                                                                                                                                                                                                                               

instance Buz Bar where                                                                                                                                                                                                                       
   punk (Bar foo) = foo

Could not deduce (b ~ Foo)
from the context (Fiz b)
  bound by the type signature for punk :: Fiz b => Bar -> b
  at Test.hs:42:5-8
  ‘b’ is a rigid type variable bound by
      the type signature for punk :: Fiz b => Bar -> b at Test.hs:42:5
Relevant bindings include punk :: Bar -> b (bound at Test.hs:42:5)
In the expression: foo
In an equation for ‘punk’: punk (Bar foo) = foo

此类型签名:

class Buz a where
  punk :: Fiz b => a -> b

punk必须能够为任何类型b返回类型b东西,因为它是Fiz实例。 所以问题不在于编译器不能推断出FooFiz实例,而是返回值不是Quux ,这是Fiz一个实例。

data Quux = Quux 

instance Fiz Quux where
  funk a = a

如果你想让函数类型返回任何Fiz实例,你可以使用ExistentionalQuantification扩展:

{-# LANGUAGE RankNTypes, ExistentialQuantification #-}   
data Foo = Foo Int
data Bar = Bar Foo
data SomeFiz = forall a . Fiz a => SomeFiz a
class Fiz a where
  funk :: a -> a

class Buz a where
  punk :: a -> SomeFiz

instance Fiz Foo where
  funk a = a

instance Buz Bar where
  punk (Bar foo) = SomeFiz foo

否则,如果你真的想要实现这个类型类,你只能通过将底部传递给funk

instance Buz Bar where
  punk _ = funk undefined
-- or for example:
instance Buz Bar where
  punk _ = funk (funk undefined)

或者通过修复funk:

instance Buz Bar where
  punk _ = fix funk

如果你能提供你想要达到的目标的更多细节,也许我会给出更多有用的答案。

你不能。

Buz类说如果a有一个Buz实例,那么对于每个有一个Fiz实例的b ,你可以从a -> b提供一个函数。 Fiz在制作b几乎没有任何帮助; funk只会给你一个b ,如果你已经有了一个b

您可能误解了GHC的错误消息。 类型推断是双向的。 在这种情况下, b来自Buz类中的punk签名。 要求的结果punk是类型的东西b每种类型b Foo不是所有类型的东西。

  ‘b’ is a rigid type variable bound by
      the type signature for punk :: Fiz b => Bar -> b at Test.hs:42:5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM