簡體   English   中英

Haskell:數據定義和Functor類

[英]Haskell: data definition and Functor class

我試圖定義數據類型Set但我在嘗試實例化仿函數類時遇到問題。

這是我的代碼:

data Set a where
    Empty :: Eq a => Set a
    Add   :: Eq a => a -> Set a -> Set a

instance Functor Set where
    fmap = setMap

setMap :: (Eq a, Eq b) => (a->b) -> Set a -> Set b 
setMap f Empty = Empty
setMap f (Add x set) = Add (f x) $ setMap f set

這就是編譯器所說的:

    No instance for (Eq a) arising from a use of ‘setMap’
      Possible fix:
        add (Eq a) to the context of
          the type signature for:
            fmap :: (a -> b) -> Set a -> Set b

為什么setMap定義中的約束不夠? 或者,如果是,為什么這是錯的?

fmap函數是一對函數:將一種類型映射到另一種類型的類型構造函數f ,以及將類型a -> b的函數映射到fa -> fb類型函數的函數fmap ab是什么沒有限制; ffmap需要適用於所有類型。

Set符合類型構造函數; 給定任何類型a ,它返回一個新類型Set a

setMap ,但是, 與任何兩種工作模式ab ; 它只適用於Eq a => aEq b => b

因此, Set / setMap幾乎 (但不完全)是從HaskHask (或Hask上的endofunctor )的Functor ,這是Functor類型類所代表的。 Hask是有爭議的類別,被定義為所有Haskell類型的類以及在這些類型上定義的函數。)


但是,可以定義一個名為HaskEqHask子類,其對象將是具有Eq實例的所有Haskell類型。 然后Set / setMap將是對HaskEq一個endofunctor,因為setMap將是有效的任何類型的HaskEq。 在Haskell中表示HaskEq沒有簡單的方法,盡管Hask很簡單,如Control.Category所示:

class Category a where
    id :: cat a a
    (.) :: cat b c -> cat a b -> cat a c

-- Hask
instance Category (->) where
    id = GHC.Base.id
    (.) = (GHC.Base..)

但是你可以定義自己的類型類來表示這樣的endofunctors:

class EqFunctor f where
    eqfmap :: (Eq a, Eq b) => (a -> b) -> f a -> f b

instance EqFunctor Set where
    eqfmap = setMap

暫無
暫無

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

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