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

时间:2016-04-09 09:02:31

标签: haskell monads

让我们考虑一下:

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的误解有关。请帮忙。

1 个答案:

答案 0 :(得分:4)

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

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

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

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

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

你想要的可能是:

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

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

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

f :: Monad m => m Int

(我认为你必须关闭单态限制以使其实际编译。)