簡體   English   中英

Haskell 類型和類型類聲明

[英]Haskell types and typeclasses declaration

我試圖更好地理解 Haskell 中的類和實例。 因此,我正在研究:

http://learnyouahaskell.com/making-our-own-types-and-typeclasses

他們建議在這里嘗試:

instance (Eq m) => Eq (Maybe m) where  
    Just x == Just y = x == y  
    Nothing == Nothing = True  
    _ == _ = False  

但是當我這樣做時,我得到以下 output:

tryouts.hs:58:10: error:
    Duplicate instance declarations:
      instance Eq m => Eq (Maybe m) -- Defined at tryouts.hs:58:10
      instance Eq a => Eq (Maybe a) -- Defined in `GHC.Maybe'
  1. 我怎樣才能克服這一點,go 實例化我自己的類型類聲明?

  2. 作者認為 class 前面的(Eq m) => Eq對於限制實例的內容很重要。 這與定義Eq時在 class 級別(例如)執行此操作明顯不同。 但是,我不確定我是否理解其中的區別。 這可能是我不明白 OOP 中類型類和常規 class 之間的區別以及前者的“繼承”性質的地方。

  1. 我怎樣才能克服這一點,go 實例化我自己的類型類聲明?

該錯誤表明在模塊中,它已經包含這樣的實例。 事實上,它在語義上是完全相同的,正如我們在源代碼中看到的那樣:

 data Maybe a = Nothing | Just a deriving ( Eq -- ^ @since 2.01, Ord -- ^ @since 2.01 )

實現Eq的默認方式是,如果兩項的數據構造函數相同,並且參數在元素方面相等,則返回True

您可以定義自己的類型,然后定義實例,例如:

data Maybe2 a = Nothing2 | Just2 a

instance Eq m => Eq (Maybe2 m) where  
    Just2 x == Just2 y = x == y  
    Nothing 2== Nothing2 = True  
    _ == _ = False

作者認為class前面的(Eq m) => Eq對於約束實例的內容很重要。 這與定義 Eq 時在 class 級別(例如)執行此操作明顯不同。 但是,我不確定我是否理解其中的區別。 這可能是我不明白 OOP 中類型類和常規 class 之間的區別以及前者的“繼承”性質的地方。

如果你會使用:

class Eq a => Eq (f a) where
    ...

那么這將意味着Eq (Maybe a)將暗示Eq a ,所以情況正好相反。 然而這永遠不會起作用,因為如果Eq (Maybe Int)是一個實例,那么Eq Int是一個實例,但Eq Int只能是一個實例,如果Int ~ faIntfa a類型相同),並且是Eq的一個實例。

  1. 您不能真正為Maybe a “重新定義” Eq ,因為它已在 Prelude 中定義。 話雖如此,您可能有一種方法可以通過{-#LANGUAGE NoImplicitPrelude #-}重新定義它,並仔細導入足夠的類型和類型類以避免導入包含Maybe aEq定義的文件,或者您可以使用其中一個編譯指示來允許重疊聲明,但我對此並不熟悉,所以不要相信我的話。

  2. Eq m => Eq (Maybe m)意味着為了讓Maybe m成為Eq類型 class 的實例, m必須已經是Eq的實例。 這是很自然的,因為為了比較Just aJust b ,您需要能夠比較ab 因此,您無法比較Just (+)Just (-)之類的相等性。

您可以使用另一種方法來嘗試使用默認情況下從Prelude導入的東西 - 使用hiding 在這種情況下,它可能如下所示:

import Prelude hiding (Maybe, Just, Nothing)

data  Maybe a  =  Nothing | Just a

instance (Eq m) => Eq (Maybe m) where  
    Just x == Just y = x == y  
    Nothing == Nothing = True  
    _ == _ = False  

暫無
暫無

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

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