簡體   English   中英

Haskell:在另一個實例中使用一個類

[英]Haskell: Using one class in instance of another

我有以下方案的代碼:

class First s where
  func1 :: s -> s
class Second a where
  func2 :: s -> a s

data D s = D {value :: s}
myFunc2 :: First s => s -> D s
myFunc2 = undefined

通常,func2的參數不能是First的實例。 我想在它的值為第一個實例的情況下制作第二個D實例。 然后我想得到這個實例:

instance Second D where
  func2 = myFunc2

但是我收到一個錯誤:

No instance for (First s)
  arising from a use of `myFunc2'

好吧,讓實例是:

instance First s => Second D where
  func2 = myFunc2

但這會給出錯誤:

Ambiguous constraint `First s'
  At least one of the forall'd type variables mentioned by the constraint
  must be reachable from the type after the '=>'
In the instance declaration for `Second D'

那么,有沒有辦法從其他類中獲取具有某些條件的類實例,但是在'=>之后沒有所有類型變量?

我認為有必要從質量上考慮什么是有意義的

class Second a where
    func2 :: s -> a s

Second實例承諾為任何類型s定義func2 myFunc2並非如此,因為myFunc2僅針對存在First實例的s定義。 這意味着,當你已經定義了FirstSecond ,不可能在Second實例中使用myFunc2 (除非存在一個全能的forall s . First s實例,但我假設沒有,或者你不會打算做一個類型類。

所以,你必須改變至少一件事。 你可以重新定義Second Grzegorz建議。 如果您不喜歡這樣,您可以重新定義Second

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}

class Second a s where
  func2 :: s -> a s

instance First s => Second D s where
  func2 = myFunc2

請注意,這與您最初寫的內容有所不同,因為現在Second實例並不保證func2是多態的。 但是我認為這更接近你所說的“當它是第一個值的實例時,只在那種情況下制作第二個實例”。 也許它會在您的代碼中被接受。

確切的解決方案將取決於代碼嘗試做什么,但問題是你給func2的類型簽名沒有提到First s約束,而你對Second D實例的func2的定義需要它。 以下編譯:

class First s where
  func1 :: s -> s
class Second a where
  func2 :: First s => s -> a s

data D s = D {value :: s}
myFunc2 :: First s => s -> D s
myFunc2 = undefined

instance Second D where
  func2 = myFunc2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM