liftM可以从liftA有什么不同?(Can liftM differ from liftA?)

2019-09-01 19:34发布

根据该Typeclassopedia (除其他来源), Applicative逻辑之间属于MonadPointed (因而Functor )在类型的类层次,所以我们非常有这样的事情,如果Haskell的前奏是今天写的:

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

class Functor f => Pointed f where
    pure :: a -> f a

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

class Applicative m => Monad m where
    -- either the traditional bind operation
    (>>=) :: (m a) -> (a -> m b) -> m b
    -- or the join operation, which together with fmap is enough
    join :: m (m a) -> m a
    -- or both with mutual default definitions
    f >>= x = join ((fmap f) x)
    join x = x >>= id
    -- with return replaced by the inherited pure
    -- ignoring fail for the purposes of discussion

(如果这些默认的释义是我从重新键入在维基百科的解释 ,错误的是我自己的,但如果有错误,但是至少在原则上可能的。)

由于库目前的定义,我们有:

liftA :: (Applicative f) => (a -> b) -> f a -> f b
liftM ::       (Monad m) => (a -> b) -> m a -> m b

和:

(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b
ap    ::       (Monad m) => m (a -> b) -> m a -> m b

注意这些类型的每对之间的相似性。

我的问题是: liftM (从不同liftA )和ap (从不同的<*>只需将历史现实的结果Monad被设计没有PointedApplicative的心灵? 或者,他们在其他一些行为方式(可能,对于一些法律Monad定义)从只需要一个版本不同的Applicative方面?

如果它们是不同的,你可以提供一组简单的定义(服从所需要的法律MonadApplicativePointed ,和Functor在Typeclassopedia描述定义和其他地方而不是由类型系统执行)针对liftAliftM不同的表现?

或者,如果他们不是明显的,你能使用这些同样的法律作为场地证明自己的等价?

Answer 1:

liftAliftMfmap.应该是相同的功能,而且必须是,如果他们满足函子法:

fmap id = id

然而,这不是Haskell的检查。

现在的应用型。 这是可能的ap<*>是不同的一些仿函数简单,因为可能有不止一个的实现,满足的种类和法律。 例如,列表中包含了多个可能的Applicative实例。 你可以声明如下一个适用:

instance Applicative [] where
  (f:fs) <*> (x:xs) = f x : fs <*> xs
  _      <*> _      = []
  pure              = repeat

ap功能仍然被定义为liftM2 id ,也就是Applicative自带免费使用每个实例Monad 。 但在这里,你必须有一个以上的类型构造的一个实例Applicative实例,两者均满足法律。 但是,如果你的单子和你的应用性函子不同意,它被认为是很好的形式有不同类型的他们。 例如, Applicative实例之上不与单子的同意[]所以你应该说newtype ZipList a = ZipList [a]然后作出新的实例ZipList而不是[]



Answer 2:

他们可以不同,但他们不应该

他们可以不同,因为他们可以有不同的实现方式:一种是在定义instance Applicative ,而另一种是在定义的instance Monad 。 但是,如果他们确实是不同的,那么我会说,是谁写的情况下,程序员写代码的误导。

你是对的:存在的功能,因为他们对历史的原因做。 人们对于事情的应该是强大的思想。



文章来源: Can liftM differ from liftA?