如何在Haskell中实现BST搜索

时间:2014-08-28 09:58:00

标签: haskell

我正在尝试理解这段代码:

search_bst :: Tree -> String -> Maybe Int 
search_bst Leaf _ = Nothing
search_bst (Node k v l r) sk =
    if sk == k then Just v
    else if sk < k then search_bst l sk
    else search_bst r sk

我可以得到这个概念,但Node k v l r是什么意思?这是否意味着search_bst接受两个参数,第一个是Node类型的实例并且有三个值?

3 个答案:

答案 0 :(得分:5)

Haskell语言的这一特性称为模式匹配。签名Tree -> String -> Maybe Int告诉您search_bst函数的第一个参数是Tree类型。 Tree数据类型可能定义如下:

data Tree = Leaf | Node String Int Tree Tree

TreeLeafNodeNode还包含4个StringInt类型的字段。 TreeTree。模式匹配现在允许您访问这些字段并拆分类型Tree的值。在你的函数中,第一种情况:

search_bst Leaf _ = Nothing

表示:如果search_bst被赋予Leaf作为第一个参数,而任何内容作为第二个参数,则返回Nothing

第二种情况:

search_bst (Node k v l r) sk =
  if sk == k then Just v
  else if sk < k then search_bst l sk
  else search_bst r sk

则表示:如果类型Tree的第一个参数是Node,则变量k,v,l和r将是Node的字段值构造函数。变量sk引用函数的第二个参数。

因此,如果你运行search_bst (Node "foo" 3 Leaf Leaf) "foo",首先会发生第一种情况。由于表达式Node "foo" 3 Leaf LeafNode而不是Leaf,因此第一种情况将失败。现在将尝试第二种情况,并且它匹配。因此k设置为"foo"v设置为3l设置为Leafr也设置为Leaf {{1}}。然后评估函数体。

您可以在“了解大好的Haskell”一书的chapter中了解有关函数定义语法的更多信息。

答案 1 :(得分:3)

search_bst :: Tree -> String -> Maybe Int

表示search_bst接受两个参数,一个类型为Tree,另一个类型为String,并生成Maybe Int

search_bst Leaf _ = ...

表示:&#34;如果第一个参数(类型Tree之一)是Leaf(类型Tree的值),则执行....最后

search_bst (Node k v l r) sk = ...

表示&#34;如果第一个参数是使用Node构造函数构建的树,并让kv,{{ 1}}和l保存作为r的参数给出的值。另请Node引用sk的第二个参数。&#34;。

  

这是否意味着search_bst需要两个参数,第一个是Node类型的实例并且有三个值?

第一个参数的类型为search_bst。您的程序中可能没有类型Tree(即使有,也与Node函数无关。)

答案 2 :(得分:3)

区分类型和(value-)构造函数非常重要。让我们考虑一个更简单的例子:你知道

data Maybe a = Just a
             | Nothing

现在,JustNothing都是值的构造函数。在任何一种情况下,这些值都具有类型 Maybe A,其中A可以是任何“包含类型”(例如Maybe Int)。 Nothing是一个无效的构造函数,因此它可以单独用于构造Maybe值。 Just是一个一元构造函数,因此它需要一个参数(包含类型)。

  

前奏&GT;没什么::可能是Int   没有
  前奏&GT; Just 3 :: Maybe Int
  只需3个

现在,实现以Maybe为参数的函数的标准方法是在这些构造函数上进行模式匹配。例如,

showMaybe :: Maybe Int -> String
showMaybe Nothing = ""
showMaybe (Just n) = show n

请注意,我解构 Just值:我给它构造了Just构造函数构造所需的新变量名,然后这些变量的值为包含数据。

在您的示例中,数据类型有点复杂

type TreeKey = String
type TreeContain = Int

data Tree = Leaf
          | Node TreeKey TreeContain Tree Tree

(通常,您会编写data Tree k v = Note k v (Tree k v) (Tree k v) | Node,它的工作方式完全相同,但可以使用其他键/值作为字符串和整数。)