gpt4 book ai didi

haskell - Haskell 应用变压器的例子

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

www.haskell.org 上的 wiki 告诉我们以下有关 Applicative Transformers 的信息:

So where are applicative transformers? The answer is, that we do not need special transformers for applicative functors since they can be combined in a generic way. http://www.haskell.org/haskellwiki/Applicative_functor#Applicative_transfomers



我尝试了以下方法来尝试组合一堆应用仿函数。但我得到的只是一堆错误。这是代码:
import Control.Applicative
import System.IO

ex x y = (:) <$> x <*> y
test1 = ex "abc" ["pqr", "xyz"] -- only this works correctly as expected
test2 = ex "abc" [Just "pqr", Just "xyz"]
test3 = ex "abc" (Just "pqr")
test4 = ex (Just 'a') ["pqr", "xyz"]
test5 = ex (return ("abc"):: IO ()) [Just "pqr", Just "xyz"]

这会产生很多类型错误,虽然我可以部分理解,但我根本无法解决它们。

错误在最后给出。

那么,例如,我如何结合 Maybe Applicative 和 List Applicative 呢?

例如,如何将 State Applicative 和 List Applicative 结合起来?
还有其他例子吗,比如说,结合了 Maybe 和 List,Maybe 和 State,最后是可怕的 IO 和 State 应用程序?

谢谢。

GHCi 错误消息如下。
example.hs:6:19:
Couldn't match expected type `[Char]' with actual type `Maybe a0'
In the return type of a call of `Just'
In the expression: Just "pqr"
In the second argument of `ex', namely `[Just "pqr", Just "xyz"]'

example.hs:7:19:
Couldn't match expected type `[[Char]]' with actual type `Maybe a0'
In the return type of a call of `Just'
In the second argument of `ex', namely `(Just "pqr")'
In the expression: ex "abc" (Just "pqr")

example.hs:8:23:
Couldn't match expected type `Maybe' with actual type `[]'
In the second argument of `ex', namely `["pqr", "xyz"]'
In the expression: ex (Just 'a') ["pqr", "xyz"]
In an equation for `test4': test4 = ex (Just 'a') ["pqr", "xyz"]

example.hs:9:21:
Couldn't match expected type `()' with actual type `[Char]'
In the first argument of `return', namely `("abc")'
In the first argument of `ex', namely `(return ("abc") :: IO ())'
In the expression:
ex (return ("abc") :: IO ()) [Just "pqr", Just "xyz"]
Failed, modules loaded: none.
Prelude>

最佳答案

考虑以下类型签名:

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

结合起来,得到的类型是:
liftA2 (<*>) :: (Applicative f, Applicative g) 
=> f (g (a -> b)) -> f (g a) -> f (g b)

这确实是两个 Applicative的组合s。事实上,它正好是两个 Applicative 的组合。 s。换句话说,虽然你可以组合 Applicative s 以一般的方式,这不是以任何方式自动完成的。一切都必须明确提升正确的次数。

您的 ex函数等价于 liftA2 (:) ,其类型为 (Applicative f) => f a -> f [a] -> f [a] .通过您的示例,对您想要做的事情进行一些猜测:
test1 = ex "abc" ["pqr", "xyz"]

这里 f[] , 我们将其应用于 [Char] 类型的参数和 [[Char]] .
test2 = ex "abc" [Just "pqr", Just "xyz"]

第二个参数的类型为 [Maybe [Char]] ,所以我们需要提升两次。第一个参数也需要解除,因为它的类型为 [Char]应该是 [Maybe Char] .
test3 = ex "abc" (Just "pqr")

这次第二个参数的类型是 Maybe [Char] , 所以 fMaybe我们只需要一部电梯。因此,第一个参数应该是 Maybe Char 类型。 .
test4 = ex (Just 'a') ["pqr", "xyz"]

这次第一个参数是 Maybe Char但第二个是 [[Char]] , 所以你有两个完全不同的 Applicative小号;两者都需要解除,给你 [Maybe Char]Maybe [Char] .
test5 = ex (return ("abc"):: IO ()) [Just "pqr", Just "xyz"]

这里的类型签名没有意义;你可能想要 IO [Char] .第二个参数的类型为 [Maybe [Char]] .与前面的示例一样,它们不匹配,但这次您有三个 Applicative s。如果你想要 IO [Maybe a] 之类的东西,您需要解除 (:)所有三个时间,例如 liftA2 (liftA2 ex) .

这种组合方式 Applicative s 称为“仿函数组合”,您链接到的页面提到了定义显式组合类型构造函数的库。例如, using the transformers library , 你可以有一个像 Compose IO (Compose [] Maybe) 这样的类型描述你的第五个例子。此组合类型定义为 Applicative以上述通用方式为例,并应用正确数量的提升操作。缺点是您需要包装和打开 newtype这需要的层。

作为附录,此声明:

So where are applicative transformers? The answer is, that we do not need special transformers for applicative functors since they can be combined in a generic way.



……有点假。确实是两个 Applicative的组成s 也是 Applicative , 但这不是组合 Applicative 的唯一方法!

考虑 StateT s m a ,相当于 s -> m (s, a) ,尽管它的定义略有不同。这也可以写成三个仿函数的组合: ((->) s) , m , 和 ((,) s) ,以及由此产生的 Functor实例是正确的,但 Applicative实例将是完全错误的。如果您从 State s a = s -> (a, s) 开始相反,没有办法定义 StateT s m通过撰写 State sm .

现在,观察非组合组合 StateT s (Either e)本质上是 Parsec 等库中使用的典型解析器组合 monad 的简化版本,此类解析器是使用 Applicative 的知名场所之一。风格很流行。因此,在 Applicative 的地方暗示 monad 转换器风格的组合在某种程度上是不必要或多余的,这似乎有点误导。被关注到!

关于haskell - Haskell 应用变压器的例子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12587195/

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