嗨,这是我的代码。
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.
答案 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]]
的结果。