我有一份作业:
1)为树定义一个数据结构TTT
,其中每个顶点有0个,1个或2个子节点,每个树叶(带有0个子节点的顶点及其自身)包含一个自然数列表;
2)创建一个函数mm
,它有两个参数 - 基于函数f(Integer->Integer)
和TTT
的树x
。结果它应该为TTT
使用函数x
为列表中的每个元素(引用1)定义提供基于f
的树;
功能f
可以有以下表示形式(a
,b
或c
):
a :: Integer -> Integer
a x = x * x
b :: Integer -> Integer
b x = x `mod` 9
c :: Integer -> Integer
c x = x * x * x
有人可以帮我吗?
答案 0 :(得分:18)
通过Learn You a Haskell for Great Good真的值得一试。这是一个很好的教程。
实践!玩!通过更改简介来扩展此分配。你能用Strings而不是Integers吗?你能用三个子树做一棵树吗?你能做一个分支机构也有数据吗?你能创建一个采用任何数据类型的树吗?了解Functor
s。他们为什么好?你能创建一个代表计算的树,用+
等操作的分支和数字离开吗?
你玩的越多,你就越自信。成为课堂上的人,在它出现之前发现了什么。每个人都会向你寻求帮助,当你被要求解决你小组中任何人遇到的棘手问题时,你会学到更多。
以下是一些提示。
这个二叉树有两个子树或一个布尔叶:
data BTree = Leaf Bool | Branch BTree BTree
deriving (Eq,Show)
此数据结构有三个项目,包括Bool
s:
data Triple = Triple Int String [Bool]
deriving (Eq,Show)
这个有三种不同的可能性,因为Expr
出现在右侧,它有点像树。
data Expr = Var Char | Lam Char Expr | Let Char Expr Expr
deriving (Eq,Show)
现在你需要一个有三种可能性的方法,其中leaf有一个Integers列表,另外两个有一个子树或两个子树。将这些想法放在一起。
我们称之为apply-a-function-anywhere-you-can-map“ping”函数。 map
为列表执行此操作,fmap
为其他内容执行此操作。
让我们定义一个函数,它接受Bool -> Bool
并将其映射到第一个例子:
mapBTree :: (Bool -> Bool) -> BTree -> BTree
mapBTree f (Leaf b) = Leaf (f b)
mapBTree f (Branch b1 b2) = Branch (mapBTree f b1) (mapBTree f b2)
和另一个映射三联的人。这次我们必须让它适用于列表中的每个Bool
。
mapBoolTriple :: (Bool -> Bool) -> Triple -> Triple
mapBoolTriple f (Triple i xs bs) = Triple i xs (map f bs)
注意我使用了标准函数map
,其功能如下:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
所以它从我的列表中的每个f
开始应用x
,从前面开始。
但这不是我真正做到这一点的方式。我要添加
{-# LANGUAGE DeriveFunctor #-}
在我的文件的顶部,这将让我写
data BinTree a = ALeaf a | ABranch (BinTree a) (BinTree a)
deriving (Eq, Show, Functor)
然后我可以做
fmap (*100) (ABranch (ALeaf 12) (ALeaf 34))
哪会给我
ABranch (ALeaf 1200) (ALeaf 3400)
但fmap
更灵活:我也可以
fmap (<20) (ABranch (ALeaf 12) (ALeaf 34))
-- ABranch (ALeaf True) (ALeaf False)
或
fmap show (ABranch (ALeaf 12) (ALeaf 34))
-- ABranch (ALeaf "12") (ALeaf "34")
没有我写一行函数fmap
。我认为这会给你10/10使用其他语言功能,但0/10解决问题设置,所以不要那样做,但要记住并尽可能使用它。
有乐趣学习Haskell。它有时令人兴奋,但它会极大地奖励你学习。你将能够用更传统的语言在Haskell中编写一些程序的十分之一的程序。多想想!写得少!
答案 1 :(得分:0)
当它按预期工作时,我已经达到了这个目的,除了我没有Ingeter列表,而是在叶子中有一个Integer。我现在的问题是我应该在这段代码中改变什么,以便叶子只能包含整数列表?到目前为止,我尝试修改树定义,如下所示:
data TTT a = ALeaf [Integer] | ABranch (TTT a) (TTT a)
并修改数据:
testTree1 = ABranch (ALeaf [1,2,3]) (ALeaf [4,5,6])
但在这种情况下,整数列表保持未修改。
下面是稳定代码,其中有一个Integer in leaf。
{-# LANGUAGE DeriveFunctor #-}
data TTT a = ALeaf a | ABranch (TTT a) (TTT a)
deriving (Eq, Show, Functor)
-- Function "mm"
mm f t = let
in fmap (f) t
-- Function "tt_a"
tt_a = mm a testTree1
-- Function "tt_b"
tt_b = mm b testTree1
-- Function "tt_c"
tt_c = mm c testTree1
-- Function "a"
a :: Integer -> Integer
a x = x * x
-- Function "b"
b :: Integer -> Integer
b x = x `mod` 9
-- Function "c"
c :: Integer -> Integer
c x = x * x * x
-- TTT type tree`s for tests
testTree1 = ABranch (ALeaf 1) (ALeaf 2)
testTree2 = ABranch (ALeaf 11) (ALeaf 12)