在 Haskell 中,您能否拥有调用其他函数但没有实现的函数的签名?
In Haskell, can you have a signature of a function that calls other functions but doesn't have an implementation?
所以我正在学习 Haskell 并且我必须实现一个 treeunzip 函数,该函数采用类型为 (Tree (a,b)) 的树,其中 'a' 和 'b'是整数,returns 是解压缩的两棵树的列表,即 (Tree a, Tree b)。
我可以得到两棵树中的一棵,但我不能将它们放在一个列表中。我想到的是:
treeunzip :: (NewTree) -> (treeunzipL, treeunzipR)
NewTree 定义为:
data NewTree = NewLeaf | NewNode Int Int NewTree NewTree deriving Show
树定义为:
data Tree = Leaf | Node Int Tree Tree deriving Show
下面是treeunzipL和treeunzipR函数,不知道有没有关系
treeunzipL :: (NewTree) -> (Tree)
treeunzipL NewLeaf = (Leaf)
treeunzipL (NewNode x y lSubTree rSubTree) = (Node x (treeunzipL (lSubTree)) (treeunzipL (rSubTree)))
treeunzipR :: (NewTree) -> (Tree)
treeunzipR NewLeaf = (Leaf)
treeunzipR (NewNode x y lSubTree rSubTree) = (Node y (treeunzipR (lSubTree)) (treeunzipR (rSubTree)))
现在显然在加载模块时给我一个错误,因为 treeunzip 有签名但没有实现。有什么办法可以解决这个问题吗?
谢谢。
您的问题似乎是您试图在类型中暗示定义。两者是分开的,必须单独提供。 (编译器可以从定义中推断出类型,但不能从类型中推断出定义。)
treeunzip :: NewTree -> (Tree, Tree)
treeunzip t = (treeunzipL t, treeunzipR t)
但是,您应该将原始类型参数化为
data Tree a = Leaf | Node a (Tree a) (Tree a)
这样你只需要一个treeunzip
函数:
treeunzip :: Tree (a, b) -> (Tree a, Tree b)
treeunzip Leaf = (Leaf, Leaf)
treeunzip (Node (a, b) left right) = ((Node a left' right'),
(Node b left'' right''))
where (left', left'') = treeunzip left
(right', right'') treeunzip right
> treeunzip (Node (1,2) (Node (3,4) Leaf Leaf) (Node (5,6) Leaf Leaf))
(Node 1 (Node 3 Leaf Leaf) (Node 5 Leaf Leaf),Node 2 (Node 4 Leaf Leaf) (Node 6 Leaf Leaf))
所以我正在学习 Haskell 并且我必须实现一个 treeunzip 函数,该函数采用类型为 (Tree (a,b)) 的树,其中 'a' 和 'b'是整数,returns 是解压缩的两棵树的列表,即 (Tree a, Tree b)。
我可以得到两棵树中的一棵,但我不能将它们放在一个列表中。我想到的是:
treeunzip :: (NewTree) -> (treeunzipL, treeunzipR)
NewTree 定义为:
data NewTree = NewLeaf | NewNode Int Int NewTree NewTree deriving Show
树定义为:
data Tree = Leaf | Node Int Tree Tree deriving Show
下面是treeunzipL和treeunzipR函数,不知道有没有关系
treeunzipL :: (NewTree) -> (Tree)
treeunzipL NewLeaf = (Leaf)
treeunzipL (NewNode x y lSubTree rSubTree) = (Node x (treeunzipL (lSubTree)) (treeunzipL (rSubTree)))
treeunzipR :: (NewTree) -> (Tree)
treeunzipR NewLeaf = (Leaf)
treeunzipR (NewNode x y lSubTree rSubTree) = (Node y (treeunzipR (lSubTree)) (treeunzipR (rSubTree)))
现在显然在加载模块时给我一个错误,因为 treeunzip 有签名但没有实现。有什么办法可以解决这个问题吗?
谢谢。
您的问题似乎是您试图在类型中暗示定义。两者是分开的,必须单独提供。 (编译器可以从定义中推断出类型,但不能从类型中推断出定义。)
treeunzip :: NewTree -> (Tree, Tree)
treeunzip t = (treeunzipL t, treeunzipR t)
但是,您应该将原始类型参数化为
data Tree a = Leaf | Node a (Tree a) (Tree a)
这样你只需要一个treeunzip
函数:
treeunzip :: Tree (a, b) -> (Tree a, Tree b)
treeunzip Leaf = (Leaf, Leaf)
treeunzip (Node (a, b) left right) = ((Node a left' right'),
(Node b left'' right''))
where (left', left'') = treeunzip left
(right', right'') treeunzip right
> treeunzip (Node (1,2) (Node (3,4) Leaf Leaf) (Node (5,6) Leaf Leaf))
(Node 1 (Node 3 Leaf Leaf) (Node 5 Leaf Leaf),Node 2 (Node 4 Leaf Leaf) (Node 6 Leaf Leaf))