这里有一些值得思考的东西.
当我编写monadic代码时,monad会对完成的操作进行排序.例如,如果我写入IO monad:
do a <- doSomething
   b <- doSomethingElse
   return (a + b)
我知道doSomething以前会被执行doSomethingElse.
现在,考虑像C这样的语言中的等效代码:
return (doSomething() + doSomethingElse());
C的语义实际上没有指定这两个函数调用将被评估的顺序,因此编译器可以随意移动它.
我的问题是这样的:我如何在Haskell中编写monadic代码,这也使得这个评估顺序未定义?理想情况下,当编译器的优化器查看代码并开始移动时,我会获得一些好处.
以下是一些可能无法完成工作的技术,但却是正确的"精神":
plus doSomething doSomethingElse并plus调度monadic调用.缺点:你失去了对monadic动作结果的分享,并且plus仍然决定什么时候最终会被评估.unsafeInterleaveIO调度推迟到评估的懒惰需求.但懒惰不同于严格的未定义顺序:特别是我确实希望我的所有monadic动作都被执行.seq不强加排序约束.从这个意义上讲,我想要一些比一元顺序更灵活的东西,但是比完全懒惰更不灵活.
在思考如何推广monad时,我想出了一个仿函数F的以下属性:
inject :: (a -> F b) -> F(a -> b) 
- 这应该是a和b中的自然变换.
如果没有更好的名称,如果存在上面显示的自然变换,我将函数F称为可绑定inject.
主要问题是,这个属性是否已经知道并且有一个名称,它是如何与仿函数的其他众所周知的属性相关的(例如,应用,monadic,尖头,可遍历等)
名称"可绑定"的动机来自以下考虑:假设M是monad而F是"可绑定"仿函数.然后有一个具有以下自然态射:
fbind :: M a -> (a -> F(M b)) -> F(M b)
这类似于monadic"bind",
bind :: M a -> (a -> M b) -> M b
除了结果用仿函数F装饰.
背后的想法fbind是,广义的monadic操作不仅可以产生单个结果M b,而且可以产生这种结果的"函数"F.我想表达一个monadic操作产生几个"计算线"而不仅仅是一个的情况; 每个"计算链"再次成为一元计算.
注意,每个仿函数F都具有态射
eject :: F(a -> b) -> a -> F b
这与"注入"相反.但并非每个仿函数F都有"注入".
具有"注入"的仿函数的示例:F t = (t,t,t)  或者F t = c -> (t,t)其中c是常量类型.F t = cFunctor(常量仿函数)或 …
monads haskell functional-programming functor category-theory
www.haskell.org上的wiki告诉我们以下关于Applicative Transformers的内容:
那么应用变形金刚在哪里?答案是,我们不需要特殊的变换器用于应用仿函数,因为它们可以通用方式组合. 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 …它的倒数似乎有可能.因为我想象列表是产品并且->是取幂,
(a*a*a...)^r = (a^r)*(a^r)....
既然我们可以定义逆,[a->r] -> a -> [r]那么不应该定义它吗?