使用haskell查找要列出的树的和
我试图在给程序输入时使用id函数应用求和。但我同意下面的说法。非常感谢您的指导使用haskell查找要列出的树的和,haskell,Haskell,我试图在给程序输入时使用id函数应用求和。但我同意下面的说法。非常感谢您的指导 data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving (Eq, Show) reduce_tree :: Tree a -> (a -> b) -> (b -> a -> b -> b) -> b reduce_tree (Leaf v) = [v] reduce_tree (Node left root right
data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving (Eq, Show)
reduce_tree :: Tree a -> (a -> b) -> (b -> a -> b -> b) -> b
reduce_tree (Leaf v) = [v]
reduce_tree (Node left root right) = reduce_tree left ++ [root] ++ reduce_tree right
输入如下:
ghci> reduce_tree (VNode (VLeaf 1) 2 (VNode (VLeaf 3) 4 (VLeaf 5)))
id sum
where sum t1 v t2 = t1 + v + t2
15
哦,如果我理解正确的话,我想你只是想把你的例子输入ghci。我建议将复杂性放在文件中:
sum_tree :: Tree Int -> Int
sum_tree t = reduce_tree t id sum
where sum t1 v t2 = t1 + v + t2
然后,在ghci中,在加载中定义了sum_tree
和reduce_tree
的文件后
ghci> sum_tree (VNode (VLeaf 1) 2 (VNode (VLeaf 3) 4 (VLeaf 5))
如果必须在ghci中完成所有操作,请注意,通常不能在ghci中使用where
,因为where
仅用于定义中。使用让。。。而在
中:
ghci> let sum t1 v t2 = t1 + v + t2 in reduce_tree (VNode (VLeaf 1) 2 (VNode (VLeaf 3) 4 (VLeaf 5))) id sum
如果出于某种原因不想使用let,可以使用lambda:
ghci> reduce_tree (VNode (VLeaf 1) 2 (VLeaf 3)) id (\t1 v t2 -> t1 + v + t2)
我是否正确理解了您的问题?哦,如果我理解正确,我认为您只是想将您的示例输入ghci。我建议将复杂性放在文件中:
sum_tree :: Tree Int -> Int
sum_tree t = reduce_tree t id sum
where sum t1 v t2 = t1 + v + t2
然后,在ghci中,在加载中定义了sum_tree
和reduce_tree
的文件后
ghci> sum_tree (VNode (VLeaf 1) 2 (VNode (VLeaf 3) 4 (VLeaf 5))
如果必须在ghci中完成所有操作,请注意,通常不能在ghci中使用where
,因为where
仅用于定义中。使用让。。。而在
中:
ghci> let sum t1 v t2 = t1 + v + t2 in reduce_tree (VNode (VLeaf 1) 2 (VNode (VLeaf 3) 4 (VLeaf 5))) id sum
如果出于某种原因不想使用let,可以使用lambda:
ghci> reduce_tree (VNode (VLeaf 1) 2 (VLeaf 3)) id (\t1 v t2 -> t1 + v + t2)
我是否正确理解了你的问题?由于我没有完全理解你的问题,以下是一些观察结果:
的类型签名表明它应该比您给定的参数多 如果reduce_tree
是一个将f
类型的值映射到a
类型的值的函数,b
似乎是三个参数的累积函数(尽管我不确定为什么两个参数不够),那么g
- 如果
实际上是一个reduce函数,而不是一个简单地将树平铺成列表的函数,那么您可以从中获得灵感 使用此函数,您可以对树的元素进行展平或求和:reduce\u tree
flattenTree :: Tree a -> [a] flattenTree tree = treefold (:) [] tree sumTree :: Num a => Tree a -> a sumTree tree = treefold (+) 0 tree
- 当你说“使用id函数应用求和”时,唯一会响起的铃声是,也许你希望使用continuations。这已在例如和(标准ML)中详细介绍。哈斯凯尔等效值为:
现在,可以用与以前完全相同的方式定义treefold :: (a -> b -> b) -> b -> Tree a -> b treefold f acc tree = tf f acc tree id where tf f acc (Leaf x) k = k (f x acc) tf f acc (Node left x right) old_k = tf f left acc new_k where new_k = \acc -> tf f right (f x acc) old_k
,只是它将使用折叠以及标识函数作为初始延续。或者,如果您想自己为遍历函数提供函数sumTree
,则可以将helper函数id
提取到顶层tf
的类型签名表明它应该比您给定的参数多 如果reduce_tree
是一个将f
类型的值映射到a
类型的值的函数,b
似乎是三个参数的累积函数(尽管我不确定为什么两个参数不够),那么g
- 如果
实际上是一个reduce函数,而不是一个简单地将树平铺成列表的函数,那么您可以从中获得灵感 使用此函数,您可以对树的元素进行展平或求和:reduce\u tree
flattenTree :: Tree a -> [a] flattenTree tree = treefold (:) [] tree sumTree :: Num a => Tree a -> a sumTree tree = treefold (+) 0 tree
- 当你说“使用id函数应用求和”时,唯一会响起的铃声是,也许你希望使用continuations。这已在例如和(标准ML)中详细介绍。哈斯凯尔等效值为:
现在,可以用与以前完全相同的方式定义treefold :: (a -> b -> b) -> b -> Tree a -> b treefold f acc tree = tf f acc tree id where tf f acc (Leaf x) k = k (f x acc) tf f acc (Node left x right) old_k = tf f left acc new_k where new_k = \acc -> tf f right (f x acc) old_k
,只是它将使用折叠以及标识函数作为初始延续。或者,如果您想自己为遍历函数提供函数sumTree
,则可以将helper函数id
提取到顶层tf
- 由于我不完全理解你的问题,以下是一些观察结果:
where
:使用下面的函数类型,我正在尝试执行树的总和来列出reduce_tree::tree a->(a->b)->(b->a->b->b)->当然,reduce_tree
是错误的,我没有注意到!你能用我提到的函数类型解释清楚吗。。我很困惑,谢谢你的答复。。实际上我想给出ghci本身的恒等函数和和函数,而不是使用let。。。例如:ghci>reduce_树(节点(叶1)2(节点(叶3)4(叶5)))id sum,其中sum t1 v t2=t1+v+t2,然后输出