Applicative是Monoidal函子:
mappend :: f -> f -> f
$ :: (a -> b) -> a -> b
<*> :: f(a -> b) -> f a -> f b
但是我在Applicative类型类的定义中没有看到任何有关Monoid的参考,您能告诉我为什么吗?
定义:
class Functor f => Applicative (f :: * -> *) where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
GHC.Base.liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
{-# MINIMAL pure, ((<*>) | liftA2) #-}
此定义中未提及该结构Monoid,但是当您这样做时
> ("ab",(+1)) <*> ("cd", 5)
>("abcd", 6)
在实现此Applicative实例时,您可以清楚地看到使用结构性Monoid“(,)String”。
另一个示例显示了使用“结构Monoid”:
Prelude Data.Monoid> (2::Integer,(+1)) <*> (1::Integer,5)
<interactive>:35:1: error:
• Could not deduce (Monoid Integer) arising from a use of ‘<*>’
from the context: Num b
bound by the inferred type of it :: Num b => (Integer, b)
at <interactive>:35:1-36
• In the expression: (2 :: Integer, (+ 1)) <*> (1 :: Integer, 5)
In an equation for ‘it’:
it = (2 :: Integer, (+ 1)) <*> (1 :: Integer, 5)
最佳答案
用“monicalal functor”(单调函子)指代的类态不是Monoid
类态,即值级类态。相反,它是类型级别的monoid。即无聊的产品monoid
type Mempty = ()
type a <> b = (a,b)
(您可能会注意到,这并不是严格意义上的monoid;仅当您将
((a,b),c)
和(a,(b,c))
视为同一类型时,它们才是同构的。)要查看这与
Applicative
有什么关系,请分别。单项仿函数,我们需要用其他术语来编写类。class Functor f => Monoidal f where
pureUnit :: f Mempty
fzip :: f a -> f b -> f (a<>b)
-- an even more “general nonsense”, equivalent formulation is
-- upure :: Mempty -> f Mempty
-- fzipt :: (f a<>f b) -> f (a<>b)
-- i.e. the functor maps a monoid to a monoid (in this case the same monoid).
-- That's really the mathematical idea behind this all.
OW
class Functor f => Monoidal f where
pureUnit :: f ()
fzip :: f a -> f b -> f (a,b)
按照
Applicative
定义标准Monoidal
类的泛型实例是一个简单的练习,反之亦然。关于
("ab",(+1)) <*> ("cd", 5)
:一般而言,这与Applicative
没有多大关系,而仅与特定于编写器的作者有关。实例是instance Monoid a => Monoidal ((,) a) where
pureUnit = (mempty, ())
fzip (p,a) (q,b) = (p<>q, (a,b))
关于haskell - Monoidal仿函数是Applicative的,但是Monoid类型类在Applicative的定义中在哪里?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50702929/