[英]How to understand functor in \g x -> fmap ($) g x
我是 Haskell 的初學者。 我知道 function fmap
需要兩個 arguments ( (a->b) -> fa ->
)並返回一個仿函數( fb
),但我無法理解以下 Z945F3FC449518A73B9F5F328CZ 表達式
*Main> :t \g x -> fmap ($) g x
\g x -> fmap ($) g x :: (t -> a -> b) -> t -> a -> b
函子在哪里?
順便說一句,我用不同的括號嘗試了幾個類似的表達式,它們給出了不同的結果:
*Main> :t \g x -> fmap ($) (g x)
\g x -> fmap ($) (g x) :: Functor f => (t -> f (a -> b)) -> t -> f (a -> b)
*Main> :t \g x -> fmap $ g x
\g x -> fmap $ g x :: Functor f => (t -> a -> b) -> t -> f a -> f b
我不明白這一點。
從
\g x -> fmap ($) g x :: (t -> a -> b) -> t -> a -> b
我們有
g :: t -> a -> b
x :: t
fmap ($) g :: t -> a -> b
fmap ($) g x :: a -> b
要找到函子,只需將g
的類型寫為某些F
和X
的類型級應用程序FX
就足夠了。
我們有
t -> a -> b = (->) t (a -> b)
因此, F = (->) t
和X = (a -> b)
。
因此, fmap
調用在(->) t
函子中起作用。 我們需要將t -> a -> b
視為類型a -> b
“包裝”在函子(->) t
下的值。
現在,我們有
($) :: (a->b) -> a -> b
-- which means
($) :: (a->b) -> (a -> b)
g :: F (a->b)
fmap ($) :: F (a->b) -> F (a->b)
fmap ($) g :: F (a->b)
-- i.e.
fmap ($) g :: t -> (a->b)
首先,正如你所說,我們有,
fmap :: Functor f
=> ( a -> b ) -> f a -> f b
($) :: (t->s) -> t -> s
g :: f a
~ f (t->s)
----------------------------------------- a ~ (t->s) ~ b
fmap ($) g :: f b
~ f (t->s)
然后將其應用於x
... 但僅將函數應用於 arguments:
fmap ($) g :: Functor f => f (t->s)
~ Functor ((->) c) => c -> (t->s)
x :: c
---------------------------------------------- f ~ ((->) c)
fmap ($) g x :: (t->s)
事實上((->) c)
是一個函子。 因此,對x
的應用程序選擇了特定的 Functor 類型,即函數的 Functor。
把這一切放在一起,
-- g x
\g x -> fmap ($) g x :: (c -> (t->s)) -> c -> (t->s)
-- compare with
fmap ($) :: f (t->s) -> f (t->s) -- Functor (f ~ ((->) c)
fmap id :: f q -> f q
id :: r -> r
事實上($)
只是一個更專業的id
,而fmap id === id
,由仿函數定律。 由於所有額外的 arguments / 實例化為它提供了更多上下文,因此該類型變得更加專業。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.