gpt4 book ai didi

haskell - 将 `do` 符号 `addStuff` 转换为 `>>=`

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

Learn You a Haskell介绍 addStuff功能:

import Control.Monad.Instances

addStuff :: Int -> Int
addStuff = do
a <- (*2) -- binds (*2) to a
b <- (+10) -- binds (+10) to b
return (a+b) -- return has type sig: 'Monad m => a -> m a'

a 的类型吗? , b , 和 return (a+b)全部 Int -> Int ?我想是的,但我不确定 bind -ing 起作用。

我尝试使用 >>= 来实现它,但我不确定如何完成它(因此 ... )。
addStuff' :: Int -> Int
addStuff' = (*2) >>= (+10) >>= ...

请给我一个提示来完成它,以及编辑我对 do 的理解符号版本。

据我了解, ...需要包含 Int -> Int 的类型.在 do版本,我可以使用 ab ,但我不确定如何使用 >>= 添加它们版本。

最佳答案

使用阅读器 monad(也称为函数 monad)时,您的类型为 a -> b , 可以改写为 (->) a b .这里实际的单子(monad)实例是

instance Monad ((->) r) where
return x = const x
f >>= g = \r -> g (f r) r

请注意,在 >>= , 类型是
(>>=) :: ((->) r a) -> (a -> ((->) r b)) -> ((->) r b)

可以改写为
(>>=) :: (r -> a) -> (a -> (r -> b)) -> (r -> b)

甚至
(>>=) :: (r -> a) -> (a -> r -> b) -> (r -> b)

如您所见, >>=确实是采用单个输入,将其应用于 f , 然后将该结果应用于 g产生一个新函数 r -> b .因此,对于您的示例,您可以使用:
addStuff' :: Int -> Int
addStuff' = (*2) >>= (+)

等等 addStuff' 10 == 30 , 因为它执行计算 (10 * 2) + (10) .注意 10被送入 (*2)(+) ,以及 (10*2) 的结果馈送到 (+)也是。将其视为
test :: Int -> (Int, Int, Int)
test = do
x <- (*2)
y <- (*3)
z <- (*5)
return (x, y, z)

结果是
> test 1
(2, 3, 5)
> test 10
(20, 30, 50)

这实质上所做的是将参数带到 test。 “之前”它已被应用,将其提供给 <- 右侧的每个函数s,然后组合得到 return .

那么,如果没有 do 符号,你怎么能写出这些呢?你可以做类似的事情
test :: Int -> (Int, Int, Int)
test =
(\r -> r * 2) >>= (\x ->
(\r -> r * 3) >>= (\y ->
(\r -> r * 5) >>= (\z ->
return (x, y, z))))

诚然,即使有格式,它也不是很可读,但要点基本上是 r被馈送到每个中间函数,这会产生一个结果,然后你会在一个元组中返回所有这三个结果。

通过一些简化,您还可以将每个嵌套的 lambda 转换为两个参数 lambda:
test =
(\r -> r * 2) >>=
(\x r -> r * 3) >>=
(\y r -> r * 5) >>=
(\z r -> const (x, y, z) r)

我还替换了最后一个 \z -> return (x, y, z)与其等价的 \z -> const (x, y, z) => \z r -> const (x, y, z) r ,所以它们都具有相同的形式。

关于haskell - 将 `do` 符号 `addStuff` 转换为 `>>=`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25255260/

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