(<*>) 无需包装第二个参数

(<*>) without having to wrap the second argument

Haskell 这里是新手。 所以 (<$>) 被定义为

(<$>) :: Functor f => (a -> b) -> f a -> f b

(<*>)定义为

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

但我觉得 Applicative 是两个概念合二为一:

  1. 一个是仿函数
  2. 其中之一是:
(<@>) :: MyConcept m => m (a -> b) -> a -> b

例如根据 Maybe:

思考

我有一个 let i = 4 和一个 let foo = Nothing :: Num a => Maybe (a -> a)。 基本上我有一个可能存在也可能不存在的函数,它接受一个 Int 和 returns 一个 Int,以及一个实际的 Int。

当然我可以通过说 i 来包装 i

foo <*> Just i

但这需要我知道 Applicative foo 包含的内容。 有什么等同于我在这里描述的吗?我将如何着手实现该功能 <@> 自己?

会是这样的:

let (<@>) func i = func <*> ??? i

您可以使用 pure:

pure :: Applicative f => a -> f a

foo <*> pure i

虽然你可以只使用 fmap:

fmap (\f -> f i) foo

fmap ($ i) foo
(<@>) :: MyConcept m => m (a -> b) -> a -> b

要查看这是否像 Applicative,请尝试从 <*>pure 派生 <@>。你会发现这是不可能的。

<@> 的更一般形式是 extract :: (Counit w) => w a -> a for comonads

你能为 Maybe 实现 extract 吗?当值为Nothing时,你会做什么?