自定义构造函数Haskell上的模式匹配

问题描述 投票:2回答:1

我的自定义类型是:

data Tree a = Leaf a | Node [Tree a] deriving (Show, Eq)

我需要写一个函数

foo :: Eq a => a -> Tree a -> [Tree a]

foo 3 (Node [Leaf 1, Leaf 3, Node [Leaf 5, Leaf 3, Leaf 6], Leaf 4, Leaf 3, Leaf 44, Leaf 3])

-- this should print [Node [leaf 5, leaf 3, leaf 6], leaf 6, leaf 44] i.e - all elements that follow a "Leaf 3" in the Tree

我的代码如下(使用模式匹配)

foo n (Leaf _) = []

foo n (Node (Node z):y:xs) = if length (Node z):y:xs < 2 then [] 
                else (foo n (Node z)):(foo n y:xs)

foo n (Node (Leaf z):y:xs) = if length (Leaf z):y:xs < 2 then [] 
                else if Leaf n == Leaf z then [y]:(foo n y:xs)
                else (foo n y:xs)

但是我收到一个错误:

• Couldn't match expected type ‘Tree a’ with actual type ‘[Tree a]’

• In the pattern: Node (Node z) : y : xs

Node (Node z) : y : xs模式可以代表输入

Node [Node [Leaf 4, Leaf 2], Leaf 6, Leaf 9, Leaf 1]

我说错了吗?这对我来说似乎很完美。

那么,为什么模式匹配失败?

haskell types constructor functional-programming pattern-matching
1个回答
1
投票

我在repl.it上设置了一个示例,但代码如下。

我做的第一件事是为函数添加一个更具体的签名,以便更容易推理。一旦完成所有工作,请随意将其更改回原点签名。从具体到抽象,比从另一个方向转移更容易。

  • 第一个问题是模式中缺少括号(这意味着你没有使用Tree a,而是试图与[Tree a]匹配。原来的(Node (Node z):y:xs)评估如下:((Node (Node z)):y:xs)。为了方便起见,我在下面的图案中添加了all@,但是你可以取代它,它不是必不可少的。
  • 第二个问题是你真的试图将[Tree a]塞进Tree a,因为这就是y:xsfoo n y:xs的意思,所以我用Node (y:xs)取代它,这是一个Tree a
  • 第三个问题是foo的模式匹配并非详尽无遗,最后添加了一个包罗万象,你会想要考虑你的预期行为并清理它。

代码如下:

module Main where

data Tree a = Leaf a | Node [Tree a] deriving (Show, Eq)

foo :: Int -> Tree Int -> [Tree Int]
foo n (Leaf _) = []

foo n (Node all@((Node z):xs)) = if length all < 2 then [] 
            else (foo n (Node z)) ++ (foo n (Node xs) )

foo n (Node all@((Leaf z):y:xs)) = if length all < 2 then [] 
            else if Leaf n == Leaf z then [y] ++ (foo n (Node (y:xs)))
            else (foo n (Node (y:xs)))
foo _ _ = []

myTree :: Tree Int
myTree = Node [Leaf 1, Leaf 3, Node [Leaf 5, Leaf 3, Leaf 6], Leaf 4, Leaf 3, Leaf 44, Leaf 3]


main :: IO ()
main = do
  print (foo 3 myTree)

输出:

[Node [Leaf 5,Leaf 3,Leaf 6],Leaf 6,Leaf 44]
© www.soinside.com 2019 - 2024. All rights reserved.