gpt4 book ai didi

haskell - 仿函数和非感应类型

转载 作者:行者123 更新时间:2023-12-02 14:20:03 25 4
gpt4 key购买 nike

我正在阅读 Typeclassopedia 中关于仿函数的部分。 .

A simple intuition is that a Functor represents a “container” of some sort, along with the ability to apply a function uniformly to every element in the container.

好的。因此,仿函数对于列表或树等归纳类型来说显得非常自然。

如果元素数量固定为较低数量,仿函数也会显得非常简单。例如,对于 Maybe,您只需要关心“Nothing”或“Just a”——两件事。

那么,你如何制作像图表这样可能有循环的东西,即 Functor 的实例?我认为更通用的说法是,非归纳类型如何“适应”仿函数?

<小时/>

我想得越多,我就越意识到有感/无感并不重要。归纳类型更容易定义fmap...

如果我想让一个图成为 Functor 的实例,我就必须在 fmap 中实现一个图遍历算法;例如,它可能必须使用辅助函数来跟踪访问的节点。此时,我现在想知道为什么要把它定义为 Functor 而不是仅仅将其编写为函数本身?例如。列表的 map 与 fmap ...?

我希望有经验、有 war 故事、有伤疤的人能够提供一些线索。谢谢!

最佳答案

假设您定义了一个这样的图表

data Graph a = Node a [Graph a]

然后 fmap 就如您所期望的那样精确定义了

instance Functor Graph where
fmap f (Node a ns) = Node (f a) (map (fmap f) ns)

现在,如果存在循环,那么我们就必须做类似的事情

foo = Node 1 [bar]
bar = Node 2 [foo]

现在,fmap 足够惰性,您可以评估其结果的一部分,而无需强制进行其余计算,因此它的工作方式与任何打结图表示形式一样!

总的来说,这就是技巧:fmap 是惰性的,所以你可以像对待 Haskell 中的任何非归纳值一样对待它的结果(:小心)。

此外,您应该定义 fmap 与随机其他函数,因为

  1. fmap 是一个很好的、众所周知的具有规则的 API
  2. 您的容器现在可以很好地容纳需要 Functor 的东西
  3. 您可以抽象出程序的其他部分,以便它们依赖于Functor,而不是您的图表

一般来说,当我看到某个东西是仿函数时,我会想“啊太棒了,我知道如何使用它”,当我看到时

superAwesomeTraversal :: (a -> b) -> Foo a -> Foo b

我有点担心这会发生意想不到的事情..

关于haskell - 仿函数和非感应类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24049683/

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