首页 > 解决方案 > 尝试理解 Haskell 中的 Applicative

问题描述

class Functor f where
    fmap :: (a -> b) -> f a -> f b

class (Functor f) => Applicative f where
    pure a = f a
    <*> :: f (a -> b) -> f a -> f b

我尝试在 Haskell中理解Applicative从Applicative的定义来看,它看起来像是Functor的子类

我假设 fmap 就像 Functor 的接口(在 Java 世界中)如果来自 Functor 的Applicative子类那么它需要从 Functor 实现 fmap,但是FunctorApplicative中的 fmap在签名上是不同的

(a -> b) -> f a -> f b
f (a -> b) -> f a -> f b

谁能解释为什么?

标签: haskell

解决方案


首先,正如@paul 提到的,您正在使用的定义有点偏离。正确的定义如下:

class Functor f where
    fmap :: (a -> b) -> f a -> f b

class Functor f => Applicative f where
    pure :: a -> f a
    (<*>) :: f (a -> b) -> f a -> f b

那么这些定义应该如何解码呢?这里要意识到的主要事情是 Haskell 类型类与 Java 接口比 Java 类有更多共同点——所以Applicative这里的定义不是定义 Java 意义上的子类,而是指定一个类型只能是一个实例,Applicative如果它已经是的一个实例Functor(即所有Applicatives 也必须实现fmap,即使它不是类型类的一部分Applicative)。有关Functorand的更多信息Applicative,我强烈推荐在线书籍Learn You a Haskell for Great Good,特别是关于“Functors, Applicative and Monoid”的部分


推荐阅读