在Haskell中,为什么应用程序需要在同一个上下文中接受态射和数据?

问题描述 投票:0回答:1

我是Haskell的新手。这可能是愚蠢的问题。

由于Applicative类型类具有apply函数,该函数在相同的上下文中使用这些函数和数据。为什么它不能与众不同,却更通用。

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

为什么我们不能写这样的东西

class Functor f => Applicative f where
    (<*>) :: Functor g => g (a -> b) -> f a -> g (f b)
    (<*>) gab fa = fmap (\g -> fmap g fa) gab

    (<<*>>) :: Functor g => (g (f a) -> f a) -> g (a -> b) -> f a -> f b
    (<<*>>) peelOuter gab fa = peelOuter $ gab <*> fa

    (>>*<<) :: Functor g => (g (f a) -> g a) -> g (a -> b) -> f a -> g b
    (>>*<<) cleanInner gab fa = cleanInner $ gab <*> fa

可以如下使用

-- Extract List from maybe
elfm :: Maybe [a] -> [a]
elfm Nothing = []
elfm (Just xs) = xs

-- Fuse List elements in Maybe []
flem :: Monoid a => Maybe [a] -> Maybe a
flem Nothing = mempty
flem (Just xs) = Just $ foldl (<>) mempty xs

Just (*2) <*> [1,2,3,4]
-- Just [2,4,6,8]
(<<*>>) elfm (Just (*2)) [1,2,3,4]
-- [2,4,6,8]
(>>*<<) flem (Just (++ "Haskell")) ["Hello, "]
-- Just "Hello, Haskell"

而且我读到,拥有Applicatives的全部要点是Functor提升多参数函数的缺点。这样对吗?

而且我认为功能应用程序不符合预期。

add :: Num a => a -> a -> a
add a b = a + b

-- I want to apply [1,2,3] as First arguments and [4,5,6] as 2nd arguments.
-- Like add 1 4, add 2 4, add 3 6
-- But it is give all possibilities of combinations like a tree

--                          <*>
--      (+1)                (+2)            (+3)
-- (1+4)(1+5)(1+6)  (2+4)(2+5)(2+6)  (3+4)(3+5)(3+6)

并且还将它们与批处理进行比较,但是没有给出非常真实的示例。请为此提供示例。

haskell functor applicative
1个回答
0
投票

Applicative的每个实例必须具有其自己的<*>实现。这就是为什么我们首先要有类型类的原因。您的代码具有类本身定义的所有方法,实例一无所有。这意味着根本没有类型类。只有一堆通用函数。所有的肉都委派给peelOutercleanInner的参数。让我们更仔细地研究它们。它们或多或少是对称的,所以peelOuter应该足够。

(<<*>>) :: Functor g => (g (f a) -> f a) -> g (a -> b) -> f a -> f b
(<<*>>) peelOuter gab fa = peelOuter $ gab <*> fa

实际上是gab应该是类型类的方法,但是存在多个问题。

第一个涉及两个函子的问题,并且对于每个pair个函子需要分别实现gab。也就是说,这里将有一个双参数类型类ApplicativePair,并且每对都需要一个单独的实例。

第二个问题是不能为每对真正的gab仿函数实现Applicative。无法从Id a提取Maybe (ID a),或从[a]提取IO [a],或...

更糟糕的是,当fg是同一个函子时,尚不清楚它是否始终可以实现。显然,当f是单声道时,则仅是join。但是,并非所有的求助词都是单子,而join恰恰是一个求助词所缺少的单子。因此,即使gab类型是可实现的,它也会违反某些monad法则。那是一件坏事?如果仍遵循适用法律,则不一定。但是,您没有提供任何法律,只有一堆功能。

© www.soinside.com 2019 - 2024. All rights reserved.