Haskell(< - )就Monad的自然变换而言

Tsh*_*nga 2 monads haskell functional-programming syntactic-sugar comonad

所以我正在玩GHCi中的hasbolt模块,我对一些贬低有好奇心.我通过创建管道连接到Neo4j数据库,如下所示

ghci> pipe <- connect $ def {credentials}
Run Code Online (Sandbox Code Playgroud)

这工作得很好.但是,我想知道(<-)运营商的类型是什么(GHCi不会告诉我).最令人沮丧的解释描述了这一点

do x <- a
   return x
Run Code Online (Sandbox Code Playgroud)

des to to to

a >>= (\x -> return x)
Run Code Online (Sandbox Code Playgroud)

但是这条线x <- a怎么样?它并不能帮助我在加return我想是因为pipe :: Pipe没有pipe :: Control.Monad.IO.Class.MonadIO m => m Pipe,但(>>=) :: Monad m => m a -> (a -> m b) -> m b这样尝试使用到desugar bindreturn/ pure不无它的工作.

理想情况下,似乎最好只创建一个Comonad实例来启用使用extract :: Monad m => m a -> a,pipe = extract $ connect $ def {creds}但它让我感到困惑,我不明白(<-).

另一个奇怪的是,(<-)作为haskell函数,它的第一个参数是一个超出范围的变量,但这并不意味着

(<-) :: a -> m b -> b
Run Code Online (Sandbox Code Playgroud)

因为不只是任何东西都可以用作自由变量.例如,您无法将管道绑定到Num类型或Bool.变量必须是"String"ish的东西,除非它实际上不是String; 你绝对不能尝试实际绑定到String.所以它似乎不是通常意义上的haskell函数(除非有一类函数从自由变量命名空间中取值...不太可能).那究竟是(<-)什么?是否可以完全替换使用extract?这是desugar /绕过它的最好方法吗?

jbe*_*man 8

我想知道(< - )运算符的类型是什么......

<-没有一个类型,它的语法的一部分do符号,你知道这是转化为序列>>=return过程被称为脱糖中.

但是x < - a ......线怎么样?

这是正常haskell代码中的语法错误,编译器会抱怨.这条线的原因:

ghci> pipe <- connect $ def {credentials}
Run Code Online (Sandbox Code Playgroud)

在ghci中工作的是repl是一种do块; 你可以把每个条目都想象成你的main函数中的一条线(它比那更毛茸茸,但这是一个很好的近似).这就是为什么你需要(直到最近)let foo = bar在ghci中声明一个绑定.

  • @Tshimanga`do`符号是*只是糖*.你可以使用`>> =`,`>>`,lambdas和`let`重写*any*`do`块.如果您愿意,可以使用unsugared语法. (3认同)
  • @Tshimanga我想我们都错误地解释了你的问题.可能有用的是观察到`a < - x`实际上并没有"提取"一个值.'Monad`给你的是_composition_(`(>> =):: Monad m => ma - >(a - > mb) - > mb`); 我们永远不能从'ma`或`mb`之一中拉出'a`或`b`类型的值(某些_concrete_`m`除外); 事实上,这种"限制"是允许haskell使用monads在保持纯度的同时完成"IO"的原因.所有这一切都是我认为@BenjaminHodgson在他建议你有更多的学习要做以完全理解Monad时所得到的 (3认同)
  • @Tshimanga和`Comonad`与此无关.在你完全理解monad(和应用程序,变换器,镜头和类别,......)之后不久,忘记comonads甚至是一件事你会更好. (2认同)
  • @Tshimanga`x < - a`不能孤立地处理任何东西,因为`x < - a`只在较大的`do`块内有效.这就像问什么`(3 +`表示 - 它不是一个有效的表达式.但是,*任何*有效的`do`块**可以转换为没有`do`表示法的代码.例如,`do {x < - a; return x}`被置于'a >> =(\ x - > return x)`(虽然这是多余的,因为它完全等同于monad定律的'a`). (2认同)
  • @jberryman是的,我认为我最初的困惑源于当我在GHCi中输入`a < - x`时,它实际上是给我一个未包装的管道.这让我觉得一般来说`a < - x`做了一些解包,尽管知道monad的自然变换实际上不能做到这一点.也许我认为在Haskell中有一些警告使得事情不像我熟悉的类别理论概念. (2认同)