[英]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
。 a
和b
是什么沒有限制; f
和fmap
需要適用於所有類型。
Set
符合類型構造函數; 給定任何類型a
,它返回一個新類型Set a
。
setMap
,但是, 不與任何兩種工作模式a
和b
; 它只適用於Eq a => a
和Eq b => b
。
因此, Set
/ setMap
對幾乎 (但不完全)是從Hask到Hask (或Hask上的endofunctor )的Functor
,這是Functor
類型類所代表的。 ( Hask是有爭議的類別,被定義為所有Haskell類型的類以及在這些類型上定義的函數。)
但是,可以定義一個名為HaskEq的Hask子類,其對象將是具有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.