Haskell 将MaybeT与'join'连用`
查看Haskell 将MaybeT与'join'连用`,haskell,Haskell,查看MaybeT变压器: ghci> let x = MaybeT $ Just 1234 ghci> let y = runMaybeT x ghci> :t y y :: Num (Maybe a) => Maybe (Maybe a) 现在我想获得内部可能是一个,但是连接不起作用 ghci> join y <interactive>:53:1: No instance for (Num (Maybe a0)) arising from
MaybeT
变压器:
ghci> let x = MaybeT $ Just 1234
ghci> let y = runMaybeT x
ghci> :t y
y :: Num (Maybe a) => Maybe (Maybe a)
现在我想获得内部可能是一个
,但是连接
不起作用
ghci> join y
<interactive>:53:1:
No instance for (Num (Maybe a0)) arising from a use of `it'
In a stmt of an interactive GHCi command: print it
ghci>join y
:53:1:
没有因使用“it”而产生的(Num(可能是a0))实例
在交互式GHCi命令的stmt中:打印它
如何获取内部
可能是一个值?可能的类型是:
MaybeT :: Monad m => m (Maybe a) -> MaybeT m a
因此,MaybeT$Just 1234
(您的问题中绑定到x
的表达式)的类型是:
Haskell number文本被重载,并将根据上下文要求进行解释。在您的例子中,“包装”的monadm
是Maybe
,编译器试图将文本1234
解释为Maybe
,但没有Num
实例。这解释了您遇到的类型错误
如果你真的想要一个可能是一个,你的代码应该是:
ghci> let x = MaybeT $ Just $ Just 1234
ghci> :t x
x :: Num a => MaybeT Maybe a
ghci> let y = runMaybeT x
ghci> :t y
y :: Num a => Maybe (Maybe a)
ghci> join y
Just 1234
但是,您更可能希望使用MaybeT
转换器将成功/失败或结果/无结果上下文添加到现有(一元)计算中。使用Identity
monad的最小示例:
ghci> let x = MaybeT $ Identity $ Just 1234
ghci> :t x
x :: Num a => MaybeT Identity a
ghci> let y = runMaybeT x
ghci> :t y
y :: Num a => Identity (Maybe a)
ghci> runIdentity y
Just 1234
您没有正确使用MaybeT
构造函数。查看类型签名:
MaybeT :: m (Maybe a) -> MaybeT m a
| | |
/-+-\ \---+---/
| | |
Just 1234 :: Num x => Maybe x
因此:
m := Maybe
x := Maybe a
因此:
MaybeT $ Just 1234 :: Num (Maybe a) => MaybeT Maybe a
MaybeT $ return $ Just 1234 :: (Num a, Monad m) => MaybeT m a
所以这里可能a
是Num
的一个实例,这显然是错误的。选项类型不是数字。为什么会出现这个问题
考虑数值文本1234
。数字文字是Haskell中的有界多态值。因此,它们的类型为numx=>x
。换句话说,1234
可以是任何类型,取决于上下文,只要该类型是Num
的实例(例如Int
,Integer
,Double
)
在代码中,多态类型x
被实例化为maybea
,这就是Haskell希望maybea
成为Num
实例的原因
我想你真正想做的是:
MaybeT :: m (Maybe a) -> MaybeT m a
return $ Just 1234 :: (Num a, Monad m) => m (Maybe a)
因此:
MaybeT $ Just 1234 :: Num (Maybe a) => MaybeT Maybe a
MaybeT $ return $ Just 1234 :: (Num a, Monad m) => MaybeT m a
现在,您可以轻松提取内部,可能是一个:
runMaybeT $ MaybeT $ return $ Just 1234 :: (Num a, Monad m) => m (Maybe a)
(runMaybeT $ MaybeT $ return $ Just 1234) >>= \x -> do
-- do something with x
-- x :: Maybe a
由于内部可能是一个
值被包装在一个monad中,所以您只需使用>=
来提取可能是一个
:
runMaybeT $ MaybeT $ return $ Just 1234 :: (Num a, Monad m) => m (Maybe a)
(runMaybeT $ MaybeT $ return $ Just 1234) >>= \x -> do
-- do something with x
-- x :: Maybe a
您也可以使用do
符号编写此代码:
do
x <- runMaybeT $ MaybeT $ return $ Just 1234
-- do something with x
-- x :: Maybe a
do
x ah,因此maybetma
中的a
应该是包装的monad
?@KevinMeredith否,maybetma
中的a
不应该是包装的monad。它应该是包装的monad中的值的类型。明确地说,maybetma
意味着一个可能是一个包装在monadm
中的值。这里包装的单子是可能是a
,而不是a
。a
只是包装在Maybe
中的值,该值依次包装在monadm
中@阿迪姆沙是对的。听他说:)从Control.Monad加入。