[英]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
定義。 這意味着,當你已經定義了First
和Second
,不可能在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.