Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何将F#stm编写为>>;=管道_Haskell_F#_Stm - Fatal编程技术网

Haskell 如何将F#stm编写为>>;=管道

Haskell 如何将F#stm编写为>>;=管道,haskell,f#,stm,Haskell,F#,Stm,有人能解释一下如何将这个FSharpx stm作为管道编写吗 stm { let! allTops = readTVar tAllTops let! thisPlayerTops = mapM removeOtherPlayersScores allTops let! markedTops = mapM markAsNonEmpty thisPlayerTops return markedTops

有人能解释一下如何将这个FSharpx stm作为管道编写吗

    stm {
        let! allTops = readTVar tAllTops
        let! thisPlayerTops = mapM removeOtherPlayersScores allTops
        let! markedTops = mapM markAsNonEmpty thisPlayerTops

        return 
            markedTops 
            |> Seq.filter fst 
            |> Seq.map snd
            |> List.ofSeq
    } 
我在想haskell就像>>=管道

谢谢

更新: 为了避免混淆,需要做一点澄清:

我在想,应该能够根据stm.Bind和stm.Return定义F#中的>>=运算符。我试着自己去做,但是我迷路了

更新2: 在托马斯的回答之后,我发布了更新版本,我认为它看起来还不错。如果我理解正确的话,由于缺少类型类,操作符>>=没有Haskell中的功能

我同意这不是F#的惯用法,但它可能是一个很好的练习

    readTVar tAllTops
    >>= mapM removeOtherPlayersScores 
    >>= mapM markAsNonEmpty 
    >>= stm.Return >> Seq.filter fst  >> Seq.map snd >> List.ofSeq
    |> atomically

谢谢

STM表达式转换为IO的主要区别是使用Haskell中的
原子方式
,即将一元结果(又称计算表达式)绑定到名称的差异语法(使用Haskell中的
操作符,
=
只是绑定操作的一个符号名,因此您可以在F#中定义它,就像
stm.bind的别名一样:

let (>>=) v f = stm.Bind(v, f)
使用运算符,可以按如下方式重写代码:

readTVar tAllTops >>= fun allTops ->
removeOtherPlayersScores allTops >>= fun thisPlayerTops ->
mapM markAsNonEmpty thisPlayerTops >>= fun markedTops ->
  markedTops 
  |> Seq.filter fst 
  |> Seq.map snd
  |> List.ofSeq
  |> stm.Return
这当然是一件有趣的事情,也是学习F#中单子的一个好方法(特别是如果你来自Haskell的背景),但它不是一种惯用的风格——F#中惯用的风格是显式地使用计算


这种方法的一个局限性(与Haskell相比)是
>=
在单子上不是多态的,所以你什么也得不到。另外,我认为大家普遍认为使用计算块更具可读性(对于F#开发者)

我知道这是等效的haskell代码,但我想要的是等效于我原来的stm的F#代码。我在想,应该可以用stm.Bind和stm.Return来定义F#中的>>=运算符。我自己也试着这么做,但我迷路了。哦,对不起,我完全误解了这个问题!我不确定是怎么回事我应该读stm.Bind类型。我根据您的运算符添加了一个更新的解决方案>>=谢谢!
readTVar tAllTops >>= fun allTops ->
removeOtherPlayersScores allTops >>= fun thisPlayerTops ->
mapM markAsNonEmpty thisPlayerTops >>= fun markedTops ->
  markedTops 
  |> Seq.filter fst 
  |> Seq.map snd
  |> List.ofSeq
  |> stm.Return