Haskell应用变形器的例子 [英] Examples of Haskell Applicative Transformers

查看:139
本文介绍了Haskell应用变形器的例子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

www.haskell.org上的wiki向我们介绍了有关应用变形金刚的以下内容:


那么应用变形金刚在哪里?答案是,我们不需要特殊的变形器来应用函子,因为它们可以通用的方式组合起来。
http://www.haskell.org/haskellwiki/Applicative_functor#Applicative_transfomers


为了尝试结合一些应用函子,我尝试了以下方法。但我得到的只是一堆错误。这里是代码:

  import Control.Applicative 
import System.IO

ex xy =(:)< $> x * y
test1 = exabc[pqr,xyz] - 只有这样才能正常工作
test2 = exabc[只是pqr,只是xyz]
test3 = exabc(只是pqr)
test4 = ex(只是'a')[pqr,xyz]
test5 = ex(return(abc ):: IO())[只是pqr,只是xyz]

很多类型错误,尽管我可以部分理解,但我根本无法解决它们。



错误在最后给出。



那么,我应该如何将Maybe Applicative和List Applicative结合起来呢?

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

谢谢。



GHCi错误消息随后显示。

  example.hs:6 :19:
无法匹配预期类型`[Char]',其实际类型为`Maybe a0'
在`Just'调用的返回类型中
在表达式中:只是 pqr
在`ex'的第二个参数中,即`[Justpqr,Justxyz]'

example.hs:7:19:
Couldn '与预期类型`[[Char]]'匹配,实际类型为`Maybe a0'
在`Just'调用的返回类型中
在`ex'的第二个参数中,即'(只是pqr)'
在表达式中:exabc(只是pqr)

example.hs:8:23:
无法匹配预期类型`可能'与实际类型`[]'
在`ex'的第二个参数中,即`[pq​​r,xyz]'
在表达式中:ex(J在'test4'的等式中:test4 = ex(Just'a')[pqr,xyz]

example.hs:9:21:
实际类型为[[Char]'
的预期类型'()'无法匹配在`return'的第一个参数中,即`(abc )'
在`ex'的第一个参数中,即`(return(abc):: IO())'
在表达式中:
ex(return(abc ):: IO())[只是pqr,只是xyz]
失败,模块加载:无。
前奏>


解决方案

这篇wiki文章说 liftA2(*)可用于组合可应用的函子。很容易看出如何从其类型中使用它:

  o ::(Applicative f,Applicative f1)=> 
f(f1(a - > b)) - > f(f1 a) - > f(f1 b)
o = liftA2(*)

f 也许 f1 [] 我们得到:

 >只是[(+1),(+ 6)]`o`只是[1,6] 
只是[2,7,7,12]

另一种方法是:

 > [只是(+1),只是(+6)]`o` [只有1,只有6] 
[只有2,只有7,只有7只只有12]

由于@McCann表示你的ex函数相当于 liftA2(:)

  test1 = liftA2(:)abc[pqr,xyz] 

要在更深的应用堆栈中使用(:),需要多个 liftA2

  * Main> (liftA2。liftA2)(:)(Justabc)(Just [pqr,xyz])
Just [apqr,axyz,bpqr,bxyz,cpqr ,cxyz]

然而,只有当两个操作数相同时,它才起作用。所以除了 liftA2 之外,您应该使用 pure 来修正关卡:

  * Main> (liftA2。liftA2)(:)(纯粹的abc)(Just [pqr,xyz])
只是[apqr,axyz,bpqr,bxyz,cpqr ,cxyz]


The wiki on www.haskell.org tells us the following about 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

I tried the following in order to try to combine a bunch of applicative functors. But all I got was bunch of errors. Here is the code:

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"]

This produces a lot of type errors, which though I can partially understand, I couldn't resolve them at all.

The errors are given at the end.

So, how do I combine the Maybe Applicative and the List Applicative for example?

How do I combine the State Applicative and the List Applicative for example? Are there any other examples, let's say, combining Maybe and List, Maybe and State and finally the dreadful of all the IO and State applicatives?

Thanks.

The GHCi error msgs follow.

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>

解决方案

The wiki article says that liftA2 (<*>) can be used to compose applicative functors. It's easy to see how to use it from its type:

o :: (Applicative f, Applicative f1) =>
     f (f1 (a -> b)) -> f (f1 a) -> f (f1 b)
o = liftA2 (<*>)

So to if f is Maybe and f1 is [] we get:

> Just [(+1),(+6)] `o` Just [1, 6] 
Just [2,7,7,12]

The other way around is:

>  [Just (+1),Just (+6)] `o` [Just 1, Just 6]
[Just 2,Just 7,Just 7,Just 12]

As @McCann said your ex function is equivalent to liftA2 (:):

test1 = liftA2 (:) "abc" ["pqr", "xyz"]

To use (:) with deeper applicative stack you need multiple applications of liftA2:

*Main> (liftA2 . liftA2) (:) (Just "abc") (Just ["pqr", "xyz"])
Just ["apqr","axyz","bpqr","bxyz","cpqr","cxyz"]

However it only works when both operands are equally deep. So besides double liftA2 you should use pure to fix the level:

*Main> (liftA2 . liftA2) (:) (pure "abc") (Just ["pqr", "xyz"])
Just ["apqr","axyz","bpqr","bxyz","cpqr","cxyz"]

这篇关于Haskell应用变形器的例子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆