gpt4 book ai didi

haskell - 为什么app在Applicative里面可用?

转载 作者:行者123 更新时间:2023-12-03 23:19:57 25 4
gpt4 key购买 nike

我正在尝试为 Snap 实现 MonadUnliftIO 并分析 Snap 类。我发现 ap 用于实现 Applicative,而 ap 需要 Monad 而 Monad 需要 Applicative。它看起来像一个循环。

直到现在我还认为不可能写出这样的东西。这种技巧的极限是什么?


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

class Applicative m => Monad m where
return :: a -> m a

instance Applicative Snap where
pure x = ...
(<*>) = ap

ap :: Monad m => m (a -> b) -> m a -> m b

最佳答案

这只适用于 Snap 一个Monad实例(此时它实际上在范围内)。

实际上,编译器在两个单独的过程中处理声明:首先它解析所有实例头

instance Applicative Snap
instance Monad Snap

...甚至没有查看实际的方法实现。这很好用:Monad看到Applicative就开心实例。

那么它已经知道 Snap是一个单子(monad)。 然后它继续对 (<*>) 进行类型检查实现,注意到它需要 Monad例如,并且...是的,它就在那里,所以也很好。

我们的实际原因 ap :: Monad m => ...主要是历史:Haskell98 Monad类(class)没有Applicative甚至 Functor作为父类(super class),所以可以编写代码 Monad m => ...然后不能使用 fmap<*> .因此 liftMap函数作为替换引入。

然后,当建立了更好的当前类层次结构时,许多实例只是通过引用已经存在的 Monad 来定义的。实例,毕竟这足以满足所有需求。

IMO 直接实现 <*> 通常是个好主意绝对fmap Monad之前例如,而不是相反。

关于haskell - 为什么app在Applicative里面可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65843114/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com