[英]Is a typeclass constraint discouraged in a typeclass method?
我知道在Haskell中不鼓勵使用數據約束 。 例如,
data Eq b => Bar b = Bar b
沒有不推薦使用的擴展程序是不可能的。 我也聽到
data Bar b = Eq b => Bar b
並不普遍,甚至不鼓勵。 (順便說一句對嗎?)
類型類中的約束條件是否相同? 例如,正在做類似的事情
class Foo a where
foo :: Eq b => a -> b
也不鼓勵Haskell? 它是在真實代碼中常見的嗎?
從用法的角度來看,類型類方法與普通的多態函數沒有什么不同,普通的多態函數只是碰巧將該類作為對其參與者類型變量中一個( 或多個 )的約束。 但是簽名中可能還有其他類型變量,這些變量需要一個類頭未提供的其他約束。 約束(通常) 是實現該功能所必需的 ,因此,需要對類方法進行約束當然是合理的–與對data
類型的約束不同,后者實際上根本沒有任何作用( data
的實現只是一些目的)數據布局,它可能不需要任何類†的任何方法。
但是,可以通過在類頭中包含額外的受約束類型變量來避免此問題:
class (Eq b) => Foo b a where
foo :: a -> b
有時,這比您的建議要好,但有時卻不一定好,例如,如果Foo
有很多方法,而其中只有一個方法與b
有關。 當然,在這種情況下,也可以僅將foo
拆分為頭部為b
的子類,而將其他方法保留在類中而沒有額外的約束。 但是,用兩個類代替一個類可能也不太好。
因此,如果您發現自己處在很自然的情況下,我認為將約束添加到類方法是完全合法的。
存在此類約束的方法的現有示例為foldMap
, traverse
和lift
。 這不是普遍存在的模式,但絕對也不是完全不常見的。
† 如果考慮類型/數據族,這看起來有些不同,但是即使那樣,您也不需要約束data
而只需要處理該數據的函數即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.