如何將以下資料型別實體化為 Functor ?
data LiftItOut f a = LiftItOut (f a)
data Parappa f g a = DaWrappa (f a) (g a)
data IgnoreOne f g a b = IgnoringSomething (f a) (g b)
data Notorious g o a t = Notorious (g o) (g a) (g t)
宣告本身不是很清楚,在右成員的括號內,是函式應用程式(我從未見過,只有基本型別的建構式)?我是haskell的新手,我只是想了解基礎知識。
uj5u.com熱心網友回復:
請編譯器向您展示如何操作。使用命令列標志-ddump-deriv,啟用DeriveFunctor語言擴展,并放在deriving Functor每個型別定義的末尾,然后編譯器將為每個型別列印 Functor 實體:
==================== Derived instances ====================
Derived class instances:
instance GHC.Base.Functor g =>
GHC.Base.Functor (Main.Notorious g o a) where
GHC.Base.fmap f_aK1 (Main.Notorious a1_aK2 a2_aK3 a3_aK4)
= Main.Notorious a1_aK2 a2_aK3 (GHC.Base.fmap f_aK1 a3_aK4)
(GHC.Base.<$) z_aK5 (Main.Notorious a1_aK6 a2_aK7 a3_aK8)
= Main.Notorious a1_aK6 a2_aK7 ((GHC.Base.<$) z_aK5 a3_aK8)
instance forall k (f :: k -> *) (g :: * -> *) (a :: k).
GHC.Base.Functor g =>
GHC.Base.Functor (Main.IgnoreOne f g a) where
GHC.Base.fmap f_aK9 (Main.IgnoringSomething a1_aKa a2_aKb)
= Main.IgnoringSomething a1_aKa (GHC.Base.fmap f_aK9 a2_aKb)
(GHC.Base.<$) z_aKc (Main.IgnoringSomething a1_aKd a2_aKe)
= Main.IgnoringSomething a1_aKd ((GHC.Base.<$) z_aKc a2_aKe)
instance (GHC.Base.Functor f, GHC.Base.Functor g) =>
GHC.Base.Functor (Main.Parappa f g) where
GHC.Base.fmap f_aKf (Main.DaWrappa a1_aKg a2_aKh)
= Main.DaWrappa
(GHC.Base.fmap f_aKf a1_aKg) (GHC.Base.fmap f_aKf a2_aKh)
(GHC.Base.<$) z_aKi (Main.DaWrappa a1_aKj a2_aKk)
= Main.DaWrappa
((GHC.Base.<$) z_aKi a1_aKj) ((GHC.Base.<$) z_aKi a2_aKk)
instance GHC.Base.Functor f =>
GHC.Base.Functor (Main.LiftItOut f) where
GHC.Base.fmap f_aKl (Main.LiftItOut a1_aKm)
= Main.LiftItOut (GHC.Base.fmap f_aKl a1_aKm)
(GHC.Base.<$) z_aKn (Main.LiftItOut a1_aKo)
= Main.LiftItOut ((GHC.Base.<$) z_aKn a1_aKo)
這看起來有點凌亂,但清理起來相當簡單:
data LiftItOut f a = LiftItOut (f a)
instance Functor f => Functor (LiftItOut f) where
fmap f (LiftItOut a) = LiftItOut (fmap f a)
data Parappa f g a = DaWrappa (f a) (g a)
instance (Functor f, Functor g) => Functor (Parappa f g) where
fmap f (DaWrappa a1 a2) = DaWrappa (fmap f a1) (fmap f a2)
data IgnoreOne f g a b = IgnoringSomething (f a) (g b)
instance Functor g => Functor (IgnoreOne f g a) where
fmap f (IgnoringSomething a1 a2) = IgnoringSomething a1 (fmap f a2)
data Notorious g o a t = Notorious (g o) (g a) (g t)
instance Functor g => Functor (Notorious g o a) where
fmap f (Notorious a1 a2 a3) = Notorious a1 a2 (fmap f a3)
還值得注意的是 your與 andLiftItOut同構,并且 your與 同構。ApIdentityTParappaProduct
uj5u.com熱心網友回復:
仿函式 f是具有關聯函式的型別建構式fmap,該函式從型別函式(a -> b)創建一個型別函式,該函式在“內部”(f a) -> (f b)應用它:(括號是多余的,僅用于清晰/強調)
fmap :: (Functor f) => ( a -> b)
-> (f a) -> (f b)
-- i.e. g :: a -> b -- from this
-- --------------------------
-- fmap g :: (f a) -> (f b) -- we get this
(讀它“fmap從到g從到” )。abf af b
你有
data LiftItOut h a = MkLiftItOut (h a) -- "Mk..." for "Make..."
------------- ----------- ------
new type, data type of the data constructor's
defined here constructor one argument (one field)
這意味著是事物h a的一種型別,可以作為 的引數。例如,(ie and )、(ie and ) 等。MkLiftItOutMaybe Inth ~ Maybea ~ Int[(Float,String)]h ~ []a ~ (Float,String)
h,a是型別變數——意思是,它們可以被任何特定型別替換,這樣整個句法運算式才有意義。
這些句法運算式包括MkLiftItOut xwhich is a thing of typeLiftItOut h a提供x的 thing of type h a;LiftItOut h a這是一個型別;h a這是一種可以作為引數出現的事物MkLiftItOut。因此我們可以在我們的程式中
v1 = MkLiftItOut ([1,2,3] :: [] Int ) :: LiftItOut [] Int
v2 = MkLiftItOut ((Just "") :: Maybe String) :: LiftItOut Maybe String
v3 = MkLiftItOut (Nothing :: Maybe () ) :: LiftItOut Maybe ()
.....
等等然后我們有
ghci> :i Functor
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
..........
這意味著這Functor f => (f a)是一種變數可以參考的事物型別,例如
-- f a
v4 = Just 4 :: Maybe Int
v41 = 4 :: Int
v5 = [4.4, 5.5] :: [] Float
v51 = 4.4 :: Float
v52 = 5.5 :: Float
v6 = (1,"a") :: ((,) Int) String -- or simpler, `(Int, String)`
v61 = "a" :: String
v7 = (\x -> 7) :: ((->) Int) Int -- or simpler, `Int -> Int`
這里a是事物f a的型別,是事物f的型別,是當給定事物的型別時,變成事物的型別的型別;等等。沒有任何東西可以被一個自己擁有型別的變數參考f。
以上f都是型別類的實體Functor。這意味著在圖書館的某處有定義
instance Functor Maybe where ....
instance Functor [] where ....
instance Functor ((,) a) where ....
instance Functor ((->) r) where ....
請注意,我們總是有f和a。f特別是,可以由多于一種成分的,但a總是有一些一個型別。
因此,在這種情況下,我們必須有
instance Functor (LiftItOut h) where ....
(......為什么?一定要說服自己;看看上述所有陳述如何適用并且是正確的)
那么實際的定義一定是
-- fmap :: (a -> b) -> f a -> f b
-- fmap :: (a -> b) -> LiftItOut h a -> LiftItOut h b
fmap g (MkLiftItOut x ) = (MkLiftItOut y )
where
y = ....
特別是,我們將有
-- g :: a -> b -- x :: (h a) -- y :: (h b)
我們甚至不知道它h是什么。
我們如何解決這個問題?當我們對, , nor什么都不知道的時候,我們怎么h b能從一個h a-type 的東西構造一個-type 的東西呢?hab
我們不能。
但是,如果我們知道這h也是一個Functor?
instance (Functor h) => Functor (LiftItOut h) where
-- fmap :: (a -> b) -> (f a) -> (f b)
-- fmap :: (a -> b) -> (LiftItOut h a) -> (LiftItOut h b)
fmap g (MkLiftItOut x ) = (MkLiftItOut y )
where
-- fmap :: (a -> b) -> (h a) -> (h b)
y = ....
希望你能完成這件事。并且也在你的問題中做其他型別。如果沒有,請針對您可能遇到任何其他問題的一種型別發布新問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/417812.html
標籤:
上一篇:從字串中消除連續重復
下一篇:創建類haskell的實體
