相关疑难解决方法(0)

放松monadic计算中的排序约束

这里有一些值得思考的东西.

当我编写monadic代码时,monad会对完成的操作进行排序.例如,如果我写入IO monad:

do a <- doSomething
   b <- doSomethingElse
   return (a + b)
Run Code Online (Sandbox Code Playgroud)

我知道doSomething以前会被执行doSomethingElse.

现在,考虑像C这样的语言中的等效代码:

return (doSomething() + doSomethingElse());
Run Code Online (Sandbox Code Playgroud)

C的语义实际上没有指定这两个函数调用将被评估的顺序,因此编译器可以随意移动它.

我的问题是这样的:我如何在Haskell中编写monadic代码,这也使得这个评估顺序未定义?理想情况下,当编译器的优化器查看代码并开始移动时,我会获得一些好处.

以下是一些可能无法完成工作的技术,但却是正确的"精神":

  • functorial风格编写代码,即编写plus doSomething doSomethingElseplus调度monadic调用.缺点:你失去了对monadic动作结果的分享,并且plus仍然决定什么时候最终会被评估.
  • 使用惰性IO,即将unsafeInterleaveIO调度推迟到评估的懒惰需求.但懒惰不同于严格的未定义顺序:特别是我确实希望我的所有monadic动作都被执行.
  • 懒惰的IO,加上立即seq'ing所有的参数.特别是,seq不强加排序约束.

从这个意义上讲,我想要一些比一元顺序更灵活的东西,但是比完全懒惰更不灵活.

monads haskell commutativity

24
推荐指数
2
解决办法
529
查看次数

仿函数的这个属性比单子强吗?

在思考如何推广monad时,我想出了一个仿函数F的以下属性:

inject :: (a -> F b) -> F(a -> b) 
Run Code Online (Sandbox Code Playgroud)

- 这应该是a和b中的自然变换.

如果没有更好的名称,如果存在上面显示的自然变换,我将函数F称为可绑定inject.

主要问题是,这个属性是否已经知道并且有一个名称,它是如何与仿函数的其他众所周知的属性相关的(例如,应用,monadic,尖头,可遍历等)

名称"可绑定"的动机来自以下考虑:假设M是monad而F是"可绑定"仿函数.然后有一个具有以下自然态射:

fbind :: M a -> (a -> F(M b)) -> F(M b)
Run Code Online (Sandbox Code Playgroud)

这类似于monadic"bind",

bind :: M a -> (a -> M b) -> M b
Run Code Online (Sandbox Code Playgroud)

除了结果用仿函数F装饰.

背后的想法fbind是,广义的monadic操作不仅可以产生单个结果M b,而且可以产生这种结果的"函数"F.我想表达一个monadic操作产生几个"计算线"而不仅仅是一个的情况; 每个"计算链"再次成为一元计算.

注意,每个仿函数F都具有态射

eject :: F(a -> b) -> a -> F b
Run Code Online (Sandbox Code Playgroud)

这与"注入"相反.但并非每个仿函数F都有"注入".

具有"注入"的仿函数的示例:F t = (t,t,t) 或者F t = c -> (t,t)其中c是常量类型.F t = cFunctor(常量仿函数)或 …

monads haskell functional-programming functor category-theory

19
推荐指数
2
解决办法
675
查看次数

Haskell应用变形金刚的例子

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"]
Run Code Online (Sandbox Code Playgroud)

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

错误在最后给出.

那么,我如何将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 …
Run Code Online (Sandbox Code Playgroud)

haskell monad-transformers applicative

11
推荐指数
4
解决办法
1756
查看次数

是否可以在haskell中编写一个函数:(r - > [a]) - > [r - > a])?

它的倒数似乎有可能.因为我想象列表是产品并且->是取幂, (a*a*a...)^r = (a^r)*(a^r)....

既然我们可以定义逆,[a->r] -> a -> [r]那么不应该定义它吗?

haskell types inverse

3
推荐指数
1
解决办法
306
查看次数