Haskell:无法将类型[Int]与Int匹配

时间:2016-03-05 18:14:40

标签: haskell

嗨,这是我的代码。

data Treeof a = Node Int a [Treeof a]  deriving (Eq,Show)

add_score :: Int -> Treeof a -> [[Int]]
add_score 0 (Node i a xs) = [[0]]
add_score n (Node i a xs) = [i]:[(map (add_score (n-1)) xs)]

我试图获取存储在树的每个节点中的Int并将其存储在列表列表中,但得到下面显示的错误,我不确定原因。

    Couldn't match type `[[Int]]' with `Int'
    Expected type: Treeof a -> Int
      Actual type: Treeof a -> [[Int]]
    In the first argument of `map', namely `(add_score (n - 1))'
    In the expression: (map (add_score (n - 1)) xs)
Failed, modules loaded: none.

编辑:将[i]:[(map(add_score(n-1))xs)]更改为[i] :( map(add_score(n-1))xs)

并收到类似的错误

    Couldn't match type `[Int]' with `Int'
    Expected type: Treeof a -> [Int]
      Actual type: Treeof a -> [[Int]]
    In the first argument of `map', namely `(add_score (n - 1))'
    In the second argument of `(:)', namely
      `(map (add_score (n - 1)) xs)
Failed, modules loaded: none.

2 个答案:

答案 0 :(得分:4)

xs的类型为[TreeOf a]。显然,你可以add_score (n-1)映射到这样的列表上,因为这会将TreeOf a作为参数。

但结果是什么?好吧,列出一个add_score (n-1)的结果。但那已经是[[Int]]了,所以你得到了

map (add_score $ n-1) xs :: [ [[Int]] ]

这是一个嵌套级别太多。现在将其包装在另一个单例列表中显然会适得其反。相反,您需要展平一个列表级别。至少有三种方法可以做到这一点:

  • 连接外部列表。

       [i] : (concat $ map (add_score $ n-1) xs)
    

    这可以用=<<(又名concatMap)更好地编写,如

       [i] : (add_score (n-1) =<< xs)
    
  • 连接内部列表。

       [i] : (map (concat . add_score (n-1)) xs)
    
  • 总结最里面的列表。

       [i] : (map (map sum . add_score (n-1)) xs)
    

你必须了解自己想要的行为;第一个似乎对我最有用。

答案 1 :(得分:2)

错误只是告诉你某个地方有太多(或太少)列表。

为什么要将map ...作为列表的单个元素:

[(map (add_score (n-1)) xs)]

乍一看,你似乎想要:

(map (add_score (n-1)) xs)

但是,由于完全应用了add_source会产生[[Int]],因此映射的类型为[[[Int]]](感谢@Carsten)。你可能会追求:

concatMap (add_score (n-1)) xs

这将连接列表并产生类型[[Int]]的结果。