Haskell Monad初学者

时间:2018-01-24 07:54:09

标签: haskell

您好我有一个我想了解的代码:

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)

一般来说,我有一点意见,但两时仍有问题。

  1. 如何在控制台中调用'unpack'?我试过了unpack (Just 5),这导致了错误。
  2. 由于'rest''Just []',我如何执行简单的列表添加? 我尝试了(Just 4): (Just [])(Just [1,2]): (Just [2,3])这两个都会导致错误。
  3. 如果有人能够展示如何执行这两项行动的基本解释,我将非常感激。

1 个答案:

答案 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类型,除非我弄错了。