阅读this Wikibook about Haskell and Category Theory basics,我了解了Functors:
仿函数本质上是类别之间的转换,所以给定 类别C和D,仿函数F:C - > d
将C中的任何对象A映射到D中的F(A)。
映射态射f:A - > C中的B至F(f):F(A) - > D中的F(B)
......听起来很不错。后来提供了一个例子:
我们也有一个示例实例:
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap _ Nothing = Nothing
这里是关键部分:类型构造函数可能将任何类型T转换为a 新类型,也许T.此外,fmap限制为Maybe类型需要一个 功能a - > b到函数可能a - >也许b。但那就是它!我们'已经 定义了两个部分,将Hask中的对象转换为对象 另一个类别(在Maybe上定义的Maybe类型和函数) 类型),以及将Hask中的态射视为态射的东西 这个类别。所以也许是一个算子。
我理解fmap
的定义是如何关键的。我很困惑"类型构造函数可能"提供了第一部分。我宁愿期待像pure
这样的东西。
如果我做对了,Maybe
宁愿将C
映射到D
。 (因此是类别级别的态射,这可能是Functor的要求)
我想你可以这样重写我的问题:是否有一个没有pure
明显实现的Functor?
答案 0 :(得分:13)
我认为你在类型和价值观之间感到困惑。以下是仿函数的定义:
让 C 和 D 为categories。从 C 到 D 的仿函数 F 是一个映射:
- 关联每个对象X∈C一个对象 F(X)∈D。
关联到每个态射 f:X→Y∈C一个态射 F(f):F(X)→F(Y)∈D这样以下条件成立:
- F(id:X→X)= id:F(X)→F(X)每个对象X∈C。
- F(g∘f)= F(g)∘F(f)所有态射 f:X→Y 和 g:Y→Z
一个类别由对象和对象之间的态射组成。
Haskell中的所有代码都是Haskell类别Hask的一部分。在 Hask :
因此,Haskell中的所有Functor
实例都是从Hask到Hask的函子(即它们是endofunctors)。
更严格地说,对于Haskell中的Functor
的所有实例:
C = Hask
。D = Hask
。现在,每个仿函数 F 是一个与每个对象关联的映射X∈C一个对象 F(X)∈D。< / p>
f : * -> *
。实际上,这正是Haskell中定义Functor
类型的方式:
class Functor (f : * -> *) where
fmap :: (x -> y) -> (f x -> f y)
在这里,fmap
是仿函数的第二部分。它是从值到值的函数。但是,Functor
本身是一个类型构造函数(即从类型到类型的映射)。这就是Maybe
是一个仿函数,[]
是仿函数的原因,但Maybe Int
和[Int]
不是仿函数。
请注意,pure
不构成仿函数定义的第一部分,因为它是从 X 的实例到 F(X)的实例的映射(即它是从值到值的函数)。但是,我们需要从 X 到 F(X)的映射(即从类型到类型的映射)。
答案 1 :(得分:4)
如果我做对了,
Maybe
宁愿将C
映射到D
。 (因此是类别级别的态射,这可能是Functor的要求)
不是真的,因为C
和D
有类别,而不是Haskell类型。 Functor
(即类型类的实例,而不是一般的仿函数)是从 Hask 类别(Haskell类型和函数的类别)到<的映射。 strong> Hask 本身;也就是说,C
和D
在这种情况下都是 Hask 。 Wikibook章节在 Hask中的Functors 部分中提到了这一点。在您的示例中,Maybe
类型构造函数通过将类型a
( Hask 中的对象)转换为类型Maybe a
来提供映射的第一部分( Hask 中的另一个对象。
我想你可以这样重写我的问题:
Functor
是否有明显的pure
实现?
一个例子是Functor
,(,) a
对。 fmap
很容易编写\f (x, y) -> (x, f y)
- 但pure
和(<*>)
要求对Monoid
a
约束,因为没有a
否则,处理额外data = as.data.frame(list(YY = rep("1962",10),
MM = rep("01",10),
DD = rep("01",10),
HH = c("00","01","02","03","04",
"05","06","07","08","09")))
date = paste(data$YY,data$MM,data$DD,sep="-")
data$dateTime = as.POSIXct(paste(date,data$HH,sep=" "),format="%Y-%m-%d %H")
值的方式。有关更多讨论和其他示例,请参阅Good examples of Not a Functor/Functor/Applicative/Monad?
答案 2 :(得分:2)
我说Applicative
实例类型会成为Either
的延伸(我只需拥有Bifunctor
的实例就可以了,但是另一方面使用它作为Monad是方便的),并且(恕我直言)不适合类似的事情:
data ABC a = A a | B a | C a
A,B,C都是&#34;同样可以&#34;。由于pure
没有明显的选择,因此根本不应提供。{1}}。但fmap
仍然完全正常。
答案 3 :(得分:2)
类别Hask将类型作为对象和函数作为箭头,因此Functor实例提供的对象映射必须将类型映射到类型。
fmap
将箭头(即地图函数a -> b
)映射到函数f的函数f a -> f b
。 Functor类型构造函数是对象的映射,即类型之间的映射。
例如,Maybe
类型构造函数将类型t
映射到类型Maybe t
,例如String
至Maybe String
。
相反,pure
将某些基础类型的值映射到相应的应用类型的值,例如“abc”和(只是“abc”)分别是String
和Maybe String
的值。