应用函子。详细输入 <*> 和 <$> 的签名
Applicative functors. Type signatures of <*> and <$> in detail
我们有签名:
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
让我们来玩一下:
(/) <$> Just 5 <*> Just 2
=> Just 2.5
((/) <$> Just 5 ) <*> Just 2
=> Just 2.5
( Just (\x -> 5/x ) ) <*> Just 2
=> Just 2.5
问题:
((/) <$> Just 5) <*> Just 2
^^^^^^^^^^^^^^^^ @@@@@@
(<$>) :: Functor f => (a -> b) -> f a -> f b
^^^
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
^^^^^^^^^^ @@@
我认为 ^^^ 部分应按其类型匹配。为什么 return 类型的 <$>
在视觉上与签名中的 <*>
输入类型不匹配?
我在这里想念什么?谢谢。
确实匹配,但是(<$>)
和(<*>)
函数的f
、a
和b
是变量,变量不一样每次使用该函数时的变量。
因此,将函数定义为更有意义:
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative g => g (c -> d) -> g c -> g d
所以这意味着 ^
和 @
确实匹配:
((/) <$> Just 5) <*> Just 2
^^^^^^^^^^^^^^^^ @@@@@@
(<$>) :: Functor f => (a -> b) -> f a -> f b
^^^
(<*>) :: Applicative g => g (c -> d) -> g c -> g d
^^^^^^^^^^ @@@
所以我们知道 (/) <$> Just 5
的类型是 f b
,g (c -> d)
,而 Just 2
的类型是 g c
。由于 Just 2
的类型为 Just 2 :: Num n => Maybe n
,因此这意味着 g ~ Maybe
和 c ~ n
(此处 x ~ y
表示 x
和 y
是同类型)。此外,我们可以推导出 f b ~ g (c -> d)
,因此 f ~ Maybe
,以及 b ~ (c -> d)
.
我们可以进一步分析(/) <$> Just 5
表达式。我们知道 Just 5
的类型是 Num m => Maybe m
,所以这意味着 a ~ m
。函数 (/)
的类型为 (/) :: Fractional k => k -> k -> k
,因此这意味着 a ~ b ~ k ~ m
,因此我们知道 (/) <$> Just 5
的类型为 (/) <$> Just 5 :: (Num m, Fractional m) => Maybe (m -> m)
,或者更简洁的 (/) <$> Just 5 :: Fractional m => Maybe (m -> m)
](Fractional m
表示 Num m
)。
因为我们已经发现 b ~ (c -> d)
,所以这意味着 m ~ c ~ d
,因此表达式的类型是:((/) <$> Just 5) <*> Just 2 :: Fractional m => Maybe m
.
我们有签名:
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
让我们来玩一下:
(/) <$> Just 5 <*> Just 2
=> Just 2.5
((/) <$> Just 5 ) <*> Just 2
=> Just 2.5
( Just (\x -> 5/x ) ) <*> Just 2
=> Just 2.5
问题:
((/) <$> Just 5) <*> Just 2
^^^^^^^^^^^^^^^^ @@@@@@
(<$>) :: Functor f => (a -> b) -> f a -> f b
^^^
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
^^^^^^^^^^ @@@
我认为 ^^^ 部分应按其类型匹配。为什么 return 类型的 <$>
在视觉上与签名中的 <*>
输入类型不匹配?
我在这里想念什么?谢谢。
确实匹配,但是(<$>)
和(<*>)
函数的f
、a
和b
是变量,变量不一样每次使用该函数时的变量。
因此,将函数定义为更有意义:
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative g => g (c -> d) -> g c -> g d
所以这意味着 ^
和 @
确实匹配:
((/) <$> Just 5) <*> Just 2
^^^^^^^^^^^^^^^^ @@@@@@
(<$>) :: Functor f => (a -> b) -> f a -> f b
^^^
(<*>) :: Applicative g => g (c -> d) -> g c -> g d
^^^^^^^^^^ @@@
所以我们知道 (/) <$> Just 5
的类型是 f b
,g (c -> d)
,而 Just 2
的类型是 g c
。由于 Just 2
的类型为 Just 2 :: Num n => Maybe n
,因此这意味着 g ~ Maybe
和 c ~ n
(此处 x ~ y
表示 x
和 y
是同类型)。此外,我们可以推导出 f b ~ g (c -> d)
,因此 f ~ Maybe
,以及 b ~ (c -> d)
.
我们可以进一步分析(/) <$> Just 5
表达式。我们知道 Just 5
的类型是 Num m => Maybe m
,所以这意味着 a ~ m
。函数 (/)
的类型为 (/) :: Fractional k => k -> k -> k
,因此这意味着 a ~ b ~ k ~ m
,因此我们知道 (/) <$> Just 5
的类型为 (/) <$> Just 5 :: (Num m, Fractional m) => Maybe (m -> m)
,或者更简洁的 (/) <$> Just 5 :: Fractional m => Maybe (m -> m)
](Fractional m
表示 Num m
)。
因为我们已经发现 b ~ (c -> d)
,所以这意味着 m ~ c ~ d
,因此表达式的类型是:((/) <$> Just 5) <*> Just 2 :: Fractional m => Maybe m
.