gpt4 book ai didi

function - 为什么 Haskell 假定返回的 monad 类型与作为参数传递的类型相同?

转载 作者:行者123 更新时间:2023-12-02 22:03:33 25 4
gpt4 key购买 nike

为什么这段代码可以编译?

--sequence_mine :: Monad m => [m a] -> m [a]
sequence_mine [] = return []
sequence_mine (elt:l) = do
e <- elt
sl <- sequence l
return (e:sl)

注意,我故意在这里注释掉了类型声明。但即使没有类型声明,代码仍然可以编译并且似乎可以按预期工作 - 这就是让我感到惊讶的地方。

据我了解,这一行应该出现歧义:

return (e:sl)

原因是 Haskell 不应该知道我们返回的是哪种类型的 monad。为什么它必须与我们接受的类型相同?

澄清更多。据我了解,如果我没有明确地将类型声明与我注释掉的类型声明类似,Haskell 应该推断出该函数具有如下类型:

sequence_mine :: (Monad m1, Monad m2) => [m1 a] -> m2 [a]

除非我通过将 m1m2 都称为 m 来明确统一它们,否则 Haskell 没有理由相信它们都指的是同类型!我想。

但事实并非如此。我在这里缺少什么?

最佳答案

好吧,让我们看看 do block 脱糖的目的:

sequence_mine (elt:l) = elt >>= \e -> (sequence l) >>= \sl -> return (e:sl)

回想一下,“绑定(bind)”运算符 >>= 具有类型签名 (Monad m) => m a -> (a -> m b) -> m b。请注意,此处的 monad m 虽然是任意的,但参数和结果类型必须相同。

因此,如果 elt 的类型为 m a,则很容易看出 return (e:sl) - 这是整个表达式 - 对于相同的 monad m,必须具有类型 m [a]

换句话说,每个 do block 只能在固定 monad 的上下文中工作。

关于function - 为什么 Haskell 假定返回的 monad 类型与作为参数传递的类型相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55341953/

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