gpt4 book ai didi

Haskell fmap 组成误区

转载 作者:行者123 更新时间:2023-12-05 08:22:19 25 4
gpt4 key购买 nike

如果我组成两个 fmap

Prelude> :t (fmap.fmap)
(fmap.fmap)
:: (Functor f, Functor f1) => (a -> b) -> f1 (f a) -> f1 (f b)

我得到一个函数,该函数将函数应用于结构的 2 个嵌套级别 f1f 中的值。

而且我可以使用它——这正如我预期的那样有效:

Prelude> (fmap.fmap) (+1) [[1,2]]
[[2,3]]

如我所料的推断类型(围绕结果的 2 级结构)

Prelude> :t  (fmap.fmap) (+1) [[1,2]]
(fmap.fmap) (+1) [[1,2]] :: Num b => [[b]]

以下不起作用。我也期待这一点(因为我们不能将 sum 应用于单个数字):

Prelude>  (fmap.fmap) sum [[1,2]]

<interactive>:39:2: error:
• Could not deduce (Num (t0 b))
from the context: (Num (t b), Num b, Foldable t)
bound by the inferred type for ‘it’:
(Num (t b), Num b, Foldable t) => [[b]]
at <interactive>:39:2-24
The type variable ‘t0’ is ambiguous
• In the ambiguity check for the inferred type for ‘it’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
When checking the inferred type
it :: forall (t :: * -> *) b.
(Num (t b), Num b, Foldable t) =>
[[b]]
Prelude> :t (fmap.fmap) sum [[1,2]]
(fmap.fmap) sum [[1,2]] :: (Num (t b), Num b, Foldable t) => [[b]]

但是!如果我将一个结构级别更改为 Maybe 类型:

Prelude> (fmap.fmap) sum Just [1,2]
Just 3

然后它开始工作,但在我看来打破了类型签名(fmap.fmap)::(Functor f, Functor f1) => (a -> b) -> f1 (f a) -> f1 (f b)(因为它在第一层结构中应用了 sum 函数,而不是我预期的第二层结构)。

我认为问题在于我理解函数应用程序顺序如何在这里评估,因为我发现使用括号这在具有可折叠列表值的两个结构级别内按预期工作(与第一个示例中的数字相比):

Prelude> (fmap.fmap) sum (Just [[1,2],[2,3]])
Just [3,5]

但是这里发生了什么:

Prelude> (fmap.fmap) sum Just [1,2]
Just 3
  1. 为什么会跳过第一层结构?

  2. 这里的函数应用顺序是什么?

  3. Haskell 如何推断最终类型?

     Prelude> :t (fmap.fmap) sum Just [1,2]
    (fmap.fmap) sum Just [1,2] :: Num t => Maybe t

为什么 Maybe t 而不是 Maybe List t 据我理解 (fmap.fmap) 必须确定 f1 (f b) 两层结构不是一层?

最佳答案

让我们计算一下,假设数字文字是 Int为了简单起见。

(fmap.fmap) sum Just [1,2]
= fmap (fmap sum) Just [1,2]
| | \ -- an additional argument applied to the result of fmap
| \ -- the value with a type of the form f a with f Functor
\ -- the function to fmap

在这里,Just是一个函数 [Int] -> Maybe [Int] , 所以第一个 fmap对仿函数 f = (->) [Int] 进行操作, 我们有 fmap = (.)因为这就是它在 Functor ((->) [Int]) 中的定义方式.

= (.) (fmap sum) Just [1,2]
= (fmap sum) (Just [1,2])

现在,fmap f (Just x) = Just (f x)因为这就是Functor Maybe已定义。

= Just (sum [1,2])
= Just 3
  1. why first level of structure skipped?

事实并非如此。第一级是(->) [Int] .

  1. what is the order of function applications here?

普通话。 fmap.fmap适用于 sum .结果应用于 Just .最终结果应用于[1,2] .

  1. how does Haskell infer the final type?

它看到 Just是一个“包裹在 (->) [Int] 仿函数中的值”,并使用它来实例化第一个 fmap .第二个fmap而是用在 Maybe 上自Just以来的水平返回那个。

关于Haskell fmap 组成误区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63228395/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com