簡體   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