2009-01-10 25 views
6

我读使用下面的例子(我会有点概括)的教程:在Haskell中解构元组时,元素可以在哪里使用?

f :: Foo -> (Int, Foo) 
... 
fList :: Foo -> [Int] 
fList foo = x : fList bar 
    where 
    (x, bar) = f foo 

我的问题在于,它似乎可以参考xbar,按名称,外面的事实获得它们的元组。如果我的猜测是正确的,这似乎就像解构其他语言的参数列表一样。 (换句话说,我不必做以下:)

fList foo = (fst tuple) : fList (snd tuple) 
     where 
     tuple = f foo 

我对这种行为是正确的吗?我从来没有在我读过的教程/书籍中看到过它的提及。有人能指点我关于这个问题的更多信息吗?

编辑:可以用类似的方式解构任何东西(列表,数组等),或者只能用元组来做这件事吗?

+1

如果您最终没有在该教程中遇到模式匹配的解释,您可能需要对Haskell进行更全面的说明。模式匹配对于该语言来说是基本和重要的。 – 2009-01-15 15:27:26

回答

13

看到您的编辑,我想你问的是什么Pattern matching

并回答你的问题:是的,任何你可以构造的,你也可以使用构造函数'解构'。例如,你可能熟悉这种形式的模式匹配:

head :: [a] -> a 
head (x:xs) = x 
head []  = error "Can't take head of empty list" 

然而,有更多的地方,你可以使用模式匹配,其他有效的符号为:

head xs = case xs of 
       (y:ys) -> y 
       []  -> error "Can't take head of empty list" 

head xs = let (y:ys) = xs 
      in y 

head xs = y 
    where 
    (y:ys) = xs 

注意,后两个示例与第一个示例有点不同,因为当您使用空列表调用它们时,它们会给出不同的错误消息。


虽然这些例子都具体到列表,你可以用其他数据类型一样,像这样:

first :: (a, b) -> a 
first tuple = x 
    where 
    (x, y) = tuple 

second :: (a, b) -> b 
second tuple = let (x, y) = tuple 
       in y 

fromJust :: Maybe a -> a 
fromJust ma = x 
    where 
    (Just x) = ma 

一遍,最后的功能也将崩溃,如果你Nothing调用它。

总结;如果你可以使用构造函数创建一些东西(比如(:)[]列表,或者(,)用于元组,或者NothingJust用于Maybe),那么可以使用这些相同的构造函数以各种方式进行模式匹配。

2

我对这种行为正确吗?

是。尽管如此,名称仅存在于您定义它们的块中。在你的情况下,这意味着你的where子句适用的逻辑单元,即fList中的表达式。

0

是的,你是对的。在where子句中绑定的名称对where子句之前的完整声明是可见的。在你的情况下,这些名称是fbar

(其中一件关于学习Haskell的硬的东西是,它不只是允许的,但通常使用在源代码中的变量在它之前,其中的变量定义的位置的位置。)

阅读的地方更多关于Haskell 98 Report中的where子句或0​​的许多精美教程之一。

1

另一种方式来看待它是这样

x where x = 3 

代码大致相当于

let x = 3 in x 
相关问题