gpt4 book ai didi

haskell - Haskell 的绑定(bind)运算符 (>>=) 是否等同于 F# 的正向管道运算符 (|>)?

转载 作者:行者123 更新时间:2023-12-02 02:51:32 24 4
gpt4 key购买 nike

Haskell 的绑定(bind)运算符 (>>=) 的类型签名:

m a -> (a -> m b) -> m b

F# 的正向管道运算符 (|>) 的类型签名:
'a -> ('a -> 'b) -> 'b

它们看起来很相似。
并且考虑到 F# 的不纯性, |> 的等效运算符在 Haskell 中是 >>= ?

例如:

haskell :
getLine >>= putStrLn

F#:
stdin.ReadLine() |> stdout.Write

最佳答案

并不真地。如果你专精 mIO , 那么有一些表面上的相似之处,所以(>>=) @IO 可能是真的有点像 F# 的 |> ,但一般来说,相似性不成立。

如果我们专业 mMaybe ,然后 >>=就像 Option.bind ,只需翻转参数(这是有道理的,因为 >>= 发音为“bind”)。

ghci> Just [1, 2, 3] >>= headMay
Just 1
ghci> Just [] >>= headMay
Nothing
ghci> Nothing >>= headMay
Nothing

如果我们专业 mEither e ,然后 >>=所做的事情类似于它为 Maybe 所做的事情, 短路 Left值而不是 Nothing .这些示例有点类似于使用 |>带有引发异常的函数,但它们并不完全相同。

如果我们专业 mParser (例如,来自 megaparsec 包),然后是 >>=生成一个运行第一个解析器的新解析器,然后使用它的结果来确定接下来运行哪个解析器。例如,这定义了一个解析器,该解析器生成一个解析器,该解析器解析两个数字或非数字后跟任意字符:
p :: Parser Char
p = anyChar >>= \c -> if isDigit c then digit else anyChar

这与 |> 完全不同。 ,因为我们没有运行任何东西,只是构建了一个稍后将应用于值的结构(解析器),但代码仍然讨论最终将提供的值(在 c 绑定(bind)中)。

如果我们专业 m(->) r ,然后 >>=实现了一种隐式参数传递。例如,如果我们有一组函数都接受一个公共(public)参数:
f :: Key -> String
g :: String -> Key -> Char
h :: Char -> Key -> Bool

…然后我们可以使用 >>=将它们组合在一起,将相同的第一个参数传递给所有它们:
ghci> :t f >>= g >>= h
f >>= g >>= h :: Key -> Bool

这明显不同于 |> ,因为我们正在执行一种函数组合,而不是函数应用。

我可以继续,但列出几十个例子可能并不比仅仅列出几个更有帮助。要点是 >>=不仅仅是为了对有效的事物进行排序,它是对哪个排序 IO 的更一般的抽象。行动是一个特例。 IO case 当然在实用上是有用的,但它也可能是理论上最不有趣的,因为它有点神奇( IO 被嵌入运行时)。 >>= 的这些其他用途一点也不神奇;它们完全使用普通的纯 Haskell 代码定义,但它们仍然非常有用,因此它们与理解 >>= 的本质更相关和 MonadIO是。

最后,Haskell 确实有一个类似于 F# 的 |> 的功能。 .它被称为 & , 它来自 Data.Function模块。它具有与 F# 中相同的类型:
(&) :: a -> (a -> b) -> b

这个函数本身就非常有用,但它与 monad 无关。

关于haskell - Haskell 的绑定(bind)运算符 (>>=) 是否等同于 F# 的正向管道运算符 (|>)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51809502/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com