您好我有一个我想了解的代码:
zipM:: Monad m => [m a] -> [m b] -> m [(a,b)]
zipM [] list = return []
zipM list [] = return []
zipM (hFirst:tFirst) (hSecond:tSecond) = do
rest <- zipM tFirst tSecond
headUnpacked <- unpack hFirst hSecond
return (headUnpacked : rest) -- rest = Just []
unpack ::Monad m => m a -> m b -> m (a,b)
unpack first second = do
fi <- first
se <- second
return (fi, se)
一般来说,我有一点意见,但两时仍有问题。
unpack (Just 5)
,这导致了错误。'rest'
是'Just []'
,我如何执行简单的列表添加?
我尝试了(Just 4): (Just [])
和(Just [1,2]): (Just [2,3])
这两个都会导致错误。如果有人能够展示如何执行这两项行动的基本解释,我将非常感激。
答案 0 :(得分:1)
您可以在GHCi中使用unpack
,如下所示:
Prelude> unpack (Just 5) (Just 42)
Just (5,42)
Prelude> unpack [[42,1337],[123]] [["foo"],["bar","baz"]]
[([42,1337],["foo"]),([42,1337],["bar","baz"]),([123],["foo"]),([123],["bar","baz"])]
Prelude> :m +Data.Monoid
Prelude Data.Monoid> unpack (Product 7, "foo") (Product 6, "bar")
(Product {getProduct = 42},("foo","bar"))
请注意,该功能适用于任何Monad
,而不仅仅适用于Maybe
。上面的GHCi会话演示了通过调用unpack
两个列表和两个元组(当第一个元素是Monad
时为Monoid
个实例)。
表达式unpack (Just 5)
没有任何内在错误:
Prelude Data.Monoid> :t unpack (Just 5)
unpack (Just 5) :: Num a => Maybe b -> Maybe (a, b)
您看到错误的原因是,正如您从上面的类型查询中看到的那样,表达式是一个函数。同样,函数没有任何问题,但GHCi不知道如何呈现函数,因为它依赖于Show
类型类将表达式转换为可打印值,而函数没有Show
个实例。
要解决第二个问题,rest
不是Just []
。首先,Just
不是类型,而是数据构造函数,但其次,即使您的意思是Maybe [a]
,也不一定是真的,因为您不知道{{1}是否有问题的是Monad
或其他Maybe
。
最后,据我所知,Monad
是调用rest
的结果,其结果的类型为unpack
。由于Monad m => m (a,b)
使用rest
表示法绑定,因此必须使用do
类型,除非我弄错了。