const ["b"] $ True ["a","b"] 为什么没有a b还有吗? > const ["a"] co-6ren">
gpt4 book ai didi

haskell - 是否有实例替代((->)r)?

转载 作者:行者123 更新时间:2023-12-02 04:22:22 24 4
gpt4 key购买 nike

我习惯了使用a <> b哪里ab接受争论。

> const ["a"] <> const ["b"] $ True
["a","b"]

为什么没有a <|> b还有吗?

> const ["a"] <|> const ["b"] $ True

<interactive>:64:13:
No instance for (Alternative ((->) Bool))
arising from a use of ‘<|>’
In the expression: const ["a"] <|> const ["b"]
In the expression: const ["a"] <|> const ["b"] $ True
In an equation for ‘it’: it = const ["a"] <|> const ["b"] $ True

最佳答案

我们想要表达类似“如果结果类型是 Alternative,那么返回该类型的函数也是 Alternative”。然而,这是不对的,因为只有 * -> * 类型可以是 Alternative

我们可能会尝试通过说对于某些Alternative f来说结果类型应该是f a来解决我们的问题,但这仍然不好,因为我们的类型想要定义实例也必须有类型 * -> *

实际上,我们只是想为 ((->) r) 和一些 Alternative f 的组合定义一个 Alternative 实例。我们可以将这个概念稍微概括为以下内容:

import Data.Functor.Compose

instance (Applicative f, Alternative g) => Alternative (Compose f g) where
empty = Compose $ pure empty
Compose a <|> Compose b = Compose $ liftA2 (<|>) a b

不幸的是,已经有一个不同的替代方案 instance对于 transformers 库中的 Compose f g ,它与上面的实例发生冲突。

或者,我们可以注意到 ReaderT r mCompose ((->) r) m 相同(模 newtype 包装) ),幸运的是,transformers 已经导出了正确的实例:

instance Alternative m => Alternative (ReaderT r m)

因此我们可以执行以下操作:

import Control.Monad.Reader

runReaderT (lift ["a"] <|> lift ["b"]) True
-- ["a", "b"]

runReaderT (empty <|> lift (Just 0)) True
-- Just 0

关于haskell - 是否有实例替代((->)r)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29432947/

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