如何实现' ex :: Maybe [[Maybe a]] - > [[a]]'方法

时间:2016-11-27 14:07:55

标签: haskell

我正在尝试在Haskell中实现类型Maybe [[Maybe a]] -> [[a]]的函数。我尝试了很多方法,但我得到的最接近的是:

ex :: Maybe [[Maybe a]] -> [[a]]
ex list = let l=list!!0 
          in []++(sequence l)

这给了我以下错误:

Couldn't match expected type `[a0]'
                with actual type `Maybe [[Maybe a]]'
    In the first argument of `(!!)', namely `list'
    In the expression: list !! 0
    In an equation for `l': l = list !! 0

我知道错误有问题,!!参数的第一个参数不是正常列表,但不能理解它。

3 个答案:

答案 0 :(得分:3)

一种可能的解决方案是:

sessionOptions = {
        cookie: {
            httpOnly: false,
            secure: false,
            maxAge: 1 * 1 * 60 * 1 * 1000
        },
        secret: "googleAPISession",
        name: "userSession",
        saveUninitialized : false,
        store: new mongoStore({
            url:"mongodb://localhost/googleServices",
            collection : "userSession",
            stringify : false
        })
    };

app.use(session(sessionOptions));

<强>方法

解决此类问题的一种方法是遵循从最外层到最内层的类型,并沿途选择适当的转换函数。在这里,我们将逐步修改ex = maybe [] (map catMaybes) 左侧的表达式,直到右侧的类型看起来像您想要的类型:

  1. 我们从::开始作为进一步转换功能的占位符,因为它始终具有正确的类型并且不执行任何操作:
    id

  2. 剥去外部id :: a -> a。如果值为Maybe,则默认为Nothing
    []

  3. 我们希望将内部maybe [] id :: Maybe [a] -> [a]转换为[Maybe a] 这可以在[a]的帮助下完成:
    catMaybes :: [Maybe a] -> [a]

  4. 实际上,我们需要maybe [] catMaybes :: Maybe [Maybe a] -> [a]而不是[[Maybe a]] -> [[a]]
    我们可以使用[Maybe a] -> [a]将功能推到列表的更深处: map :: (a -> a) -> [a] -> [a]

  5. 工具

    • 使用 GHCi 进行实验。您可以使用maybe [] (map catMaybes) :: Maybe [[Maybe a]] -> [[a]]命令询问表达式的类型,例如::t
    • 使用API​​搜索引擎查找转化功能。例如Hayoo或Hoogle。您可以输入类型签名作为搜索查询。例如,:t maybe [] id将返回[Maybe a] -> [a]等。

答案 1 :(得分:1)

查看签名ex :: Maybe [[Maybe a]] -> [[a]]。您要做的第一件事是在您的参数的不同构造函数上进行模式匹配:

ex :: Maybe [[Maybe a]] -> [[a]]
ex (Just list) = undefined
ex Nothing = undefined

因此我们必须处理两种情况。对于Nothing,您很可能只返回[]。对于Just案例,您可能希望获取内部列表中的所有Just元素:

ex :: Maybe [[Maybe a]] -> [[a]]
ex (Just list) = catInnerMaybes list
ex Nothing = []

catInnerMaybes :: [[Maybe a]] -> [[a]]
catInnerMaybes (xs:xss) = undefined
catInnerMaybes [] = undefined

对于catInnerMaybes,我们想要对我们的参数进行模式匹配,而不是使用像(!!)这样的方法。我现在暂时把剩下的留给你,但这里还有一些提示:

  • 尝试使用:代替++,因为这是处理列表的更自然,惯用的方法,因为++很快就会变慢。
  • 我认为你不想sequence。您可能取决于您的具体操作,但我认为您更有可能在catMaybes中寻找Data.Maybe。但是我建议你不要使用它,但要自己实现它以获得学习效果。

答案 2 :(得分:0)

jpath说您可以查找catMaybes函数,但最好由您自己实现学习。但如果有人来这里不是为了学习而只是为了获得完整的解决方案,那么它就是:

import Data.Maybe (catMaybes)

ex :: [[Maybe a]] -> [[a]]
ex = map catMaybes