簡體   English   中英

Haskell:f a的實際含義是什么?

[英]Haskell: What does type f a actually mean?

我偶然發現這段代碼fold ((,) <$> sum <*> product)類型簽名:: (Foldable t, Num a) => ta -> (a, a)我完全迷失了。

我知道它的作用,但我不知道怎么做。 所以我試着把它分成幾小塊:

λ: :t (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
λ: :t (,)
(,) :: a -> b -> (a, b)
λ: :t sum
sum :: (Foldable t, Num a) => t a -> a

一切都很好,只是基本的東西。

λ: :t (,) <$> sum
(,) <$> sum :: (Foldable t, Num a) => t a -> b -> (a, b)

而我又迷失了......

我看到有一些神奇的事情會變成ta -> a into fa但它是如何完成的對我來說是個謎。 sum甚至不是Functor實例!)

我一直認為fa是某種箱f包含a ,但它看起來像含義深刻得多。

您的示例中的仿函數f是所謂的“reader functor”,其定義如下:

newtype Reader r = Reader (r -> a)

當然,在Haskell中,這是為函數本地實現的,因此在運行時沒有包裝或解包。

相應的FunctorApplicative實例如下所示:

instance Functor f where
  fmap :: (a -> b) -> (r -> a)_-> (r -> b)
  fmap f g = \x -> f (g x) -- or: fmap = (.)

instance Applicative f where
  pure :: a -> (r -> a) -- or: a -> r -> a
  pure x = \y -> x -- or: pure = const
  (<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)
  frab <*> fra = \r -> frab r (fra r)   

在某種程度上,讀者仿函數也是一個“盒子”,就像所有其他仿函數一樣,具有產生類型a的上下文r

那么讓我們看看(,) <$> sum

:t (,) :: a -> b -> (a, b)
:t fmap :: (d -> e) -> (c -> d) -> (c -> e)
:t sum :: Foldable t, Num f => t f -> f

我們現在可以將d類型專門化為a ~ feb -> (a, b)ctf 現在我們得到:

:t (<$>) -- spcialized for your case
:: Foldable t, Num f => (a -> (b -> (a, b))) -> (t f -> f) -> (t f -> (b -> (a, b)))
:: Foldable t, Num f => (f -> b -> (f, b)) -> (t f -> f) -> (t f -> b -> (f, b))

應用功能:

:t (,) <$> sum
:: Foldable t, Num f => (t f -> b -> (f, b))

這正是ghc所說的。

簡短的回答是f ~ (->) (ta) 要了解原因,只需稍微重新排列sum的類型簽名,使用->作為前綴運算符而不是中綴運算符。

sum :: (Foldable t, Num a) => (->) (t a) a
                              ~~~~~~~~~~
                                  f

通常, (->) r是任何參數類型r的仿函數。

instance Functor ((->) r) where
    fmap = (.)

通過將((->) r)插入到ffmap類型中,很容易證明(.)fmap唯一可能的實現:

fmap :: (a -> b) -> f a -> f b
     :: (a -> b) -> ((->) r) a -> ((->) r) b
     :: (a -> b) -> (r -> a) -> (r -> b)

這是合成的類型簽名,合成是具有此類型簽名的唯一函數。


由於Data.Functor<$>定義為fmap的中綴版本,我們有

(,) <$> sum == fmap (,) sum
            == (.) (,) sum

從這里開始,確認結果類型確實是(Foldable t, Num a) => ta -> b -> (a, b) ,這是一個相對簡單但又繁瑣的工作。 我們有

(b' -> c') -> (a' -> b') -> (a' -> c')  -- composition
b' -> c' ~ a -> b -> (a,b)              -- first argument (,)
a' -> b' ~ t n -> n                     -- second argument sum
----------------------------------------------------------------
a' ~ t n
b' ~ a ~ n
c' ~ a -> b -> (a,b)
----------------------------------------------------------------
a' -> c' ~ t a -> b -> (a,b)

暫無
暫無

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

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