haskell - 嵌套的空列表

时间:2011-07-10 14:39:02

标签: haskell nested-lists

Hello Haskellers和Haskellettes,

在阅读http://learnyouahaskell.com/时,我的一位朋友提出了一个问题:

在Haskell中是否可以编写一个递归函数,如果所有子子列表都为空,则该函数给出True。我的第一个猜测是 - 应该是 - 但是我在编写类型注释时遇到了一个大问题。

他试过像

这样的东西
nullRec l = if null l
               then True
               else if [] `elem` l
                    then nullRec (head [l]) && nullRec (tail l)
                    else False

是 - 不工作 - : - )

我想出了像

这样的东西
  • 用concat折叠 - 获得一个长列表
    (给我实施问题)
  • 或制作无限的树状数据类型 - 并从列表中进行此处 (尚未实施)

但后者对于这个问题听起来有点过分。 你有什么想法 - 在这样一个阳光明媚的星期天; - )

提前致谢


作为对所有评论的反应 - 这是我想添加的糟糕风格 这只是一个实验
请勿在家中尝试此操作!; - )

2 个答案:

答案 0 :(得分:5)

类型类怎么样?

{-# LANGUAGE FlexibleInstances, OverlappingInstances #-}

class NullRec a where
  nullRec :: a -> Bool

instance NullRec a => NullRec [a] where
  nullRec [] = True
  nullRec ls = all nullRec ls

instance NullRec a where
  nullRec _  = False

main = print . nullRec $ ([[[[()]]]] :: [[[[()]]]])

答案 1 :(得分:4)

由于以下原因,仅使用参数多态无法实现这一点。

考虑以下这些值:

x = [8] :: [Int]
y = [3.0] :: [Double]
z = [[]] :: [[Int]]

显然,您希望自己的功能同时适用于xy,因此其类型必须为null1 :: [a] -> Bool(有人可以帮助我使这个论点看起来正式吗?我怎样才能证明这是与[Int] -> Bool[Double] -> Bool统一的唯一最具特色的无上下文类型?这个关系是否有名称?类型之间?)

现在,如果您有这种类型,那么null1 z将等于null1 x,因为它们仅在列表元素的值上有所不同,这些值是从中抽象出来的。 (甚至没有接近正式证据:()

z的所需内容为null2 :: [[a]] -> Bool,其行为会有所不同,因此null1null2同名将需要重载。 (参见FUZxxl的回答)