我正在尝试理解这段代码:
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
类型的实例并且有三个值?
答案 0 :(得分:5)
Haskell语言的这一特性称为模式匹配。签名Tree -> String -> Maybe Int
告诉您search_bst
函数的第一个参数是Tree
类型。 Tree
数据类型可能定义如下:
data Tree = Leaf | Node String Int Tree Tree
Tree
是Leaf
或Node
。 Node
还包含4个String
,Int
类型的字段。 Tree
和Tree
。模式匹配现在允许您访问这些字段并拆分类型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 Leaf
是Node
而不是Leaf
,因此第一种情况将失败。现在将尝试第二种情况,并且它匹配。因此k
设置为"foo"
,v
设置为3
,l
设置为Leaf
,r
也设置为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
构造函数构建的树,并让k
,v
,{{ 1}}和l
保存作为r
的参数给出的值。另请Node
引用sk
的第二个参数。&#34;。
这是否意味着search_bst需要两个参数,第一个是Node类型的实例并且有三个值?
第一个参数的类型为search_bst
。您的程序中可能没有类型Tree
(即使有,也与Node
函数无关。)
答案 2 :(得分:3)
区分类型和(value-)构造函数非常重要。让我们考虑一个更简单的例子:你知道
data Maybe a = Just a
| Nothing
现在,Just
和Nothing
都是值的构造函数。在任何一种情况下,这些值都具有类型 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
,它的工作方式完全相同,但可以使用其他键/值作为字符串和整数。)