我如何使用 >>= 链接基本的 Int 操作?

How do I use >>= to chain basic Int operations?

让我们考虑一下:

f :: Int
f = return 64 >>= (\x -> x^2) >>= (\y -> y^2)

GHCi 拒绝了我的代码

    Couldn't match expected type `Int' with actual type `m0 b0'
    In the expression: return 64 >>= (\ x -> x ^ 2) >>= (\ y -> y ^ 2)
    In an equation for `f':
        f = return 64 >>= (\ x -> x ^ 2) >>= (\ y -> y ^ 2)
Failed, modules loaded: none.

结果应该或至少与 281,474,976,710,656 有关(64 的平方然后提高结果的四次方)。 我无法解决这个问题。这与我对单子的误解有关。请帮忙

我们需要看看 (>>=)。它有类型

(>>=) :: Monad m => m a -> (a -> m b) -> m b

英语:(>>=) 的第二个参数必须是产生一元值的函数。你的函数只产生数字。

之所以会产生混淆,是因为您声明 f 将是 Int。然而编译器知道 (>>=) 将 return a m b 因此错误消息:由于您的注释,它希望找到 Int,但它得到的只是 m0 b0

请注意,您的 f 代码对于既是具有合理实现 (^) 的数字又是 monad 的类型来说可能是正确的。但是Int不是这种类型。

你想要的大概是:

f = return 64 >>= pure . (^2) >>= pure . (^4)

f = (\x -> (x^2)^4) <$> return 64

但这仍然不是普通的 Int,而是某些 monad 中的 Int!因此:

f :: Monad m => m Int

(我认为您必须关闭单态限制才能使其真正编译。)