gpt4 book ai didi

scala - 控制流的单子(monad)——序列、选择和迭代

转载 作者:行者123 更新时间:2023-12-04 12:08:50 25 4
gpt4 key购买 nike

我可以看到您如何使用 Monad is Haskell 进行 IO - 围绕此操作的计算创建一个容器。您可以使用 Monads 来“将计算连接在一起”是有道理的——就像您为数据流操作组合函数一样。

我只是想知道的是,您可以将 Monads 用于控制流。现在我理解控制流是关于序列、选择和迭代的。现在我已经习惯了高阶函数,比如 map、foldl、filter 和 zipwith/mapcat 来对列表执行操作。

我的问题是 - 我可以使用单子(monad)进行序列、选择和迭代以实现控制流吗?
(很高兴在 Haskell、Scala 或 Clojure 中得到答案)

最佳答案

为了在 Haskell 中排序,你有函数 >>=sequence :

(>>=) :: Monad m => m a -> (a -> m b) -> m b
sequence :: Monad m => [m a] -> m [a]
>>=或 bind 函数接受一个单子(monad) Action ,从中提取值并将其提供给一个返回新单子(monad) Action 的函数。 sequence function 获取相同类型的单子(monad)操作列表并执行所有操作,聚合它们的结果并将其包装为单个操作。

对于迭代,您有 mapMforM ( forM = flip mapM)
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapMforM函数用于应用一个函数,该函数将一个 Action 返回到列表中的每个元素,将结果聚合为单个 Action 。

对于选择,我假设您的意思是条件,在 Haskell 中作为 if-the-else 表达式实现。它们可以直接用在单子(monad)表达式中,就像它们可以用在纯表达式中一样。但是,您也可以使用某些 monad 来执行选择或至少处理错误。最容易理解的是 Maybe单子(monad):
data Maybe a = Nothing | Just a

instance Monad Maybe where
return a = Just a
(Just a) >>= f = f a
Nothing >>= f = Nothing

它有一个非常简单的实现。本质上,如果您尝试对 Nothing 进行排序进入其他任何内容,它将返回 Nothing每次。这为您提供了短路故障的概念:
lookup :: Eq a => a -> [(a, b)] -> Maybe b
-- Looks up a value in a key-value association list

myFunc :: Int -> [(String, Int)] -> Maybe Int
myFunc mult assocList = do
i <- lookup "foo" assocList
j <- lookup "bar" assocList
return $ i * mult + j

在这里,如果查找 "foo"失败, myFunc立即返回 Nothing .同样,如果查找 "bar"失败, myFunc立即返回 Nothing .只有当两个查找都成功时, myFunc做任何计算。这提供了一种“错误处理”。有一个类似的单子(monad) Either a
data Either a b = Left a | Right b

instance Monad (Either a) where
return a = Right a
(Right a) >>= f = f a
(Left a) >>= f = Left a

它的工作原理非常相似,除了“失败”值可以携带一些上下文,例如字符串错误消息或失败点的计算状态。

关于scala - 控制流的单子(monad)——序列、选择和迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20170703/

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