2016-01-25 71 views
4

我想了解this article中的代碼。它解釋了歸納圖的使用,這看起來非常好,並且在某個時候它定義了歸納圖的深度優先搜索。它的代碼如下:Haskell類型映射( - >運算符)在where子句中?

dfs :: Graph.Node -> Gr a b -> [Node] 
dfs start graph = go [start] graph 
    where go [] _       = [] 
     go _ g | Graph.isEmpty g   = [] 
     go (n:ns) (match n -> (Just c, g)) = 
      n : go (Graph.neighbors' C++ ns) g 
     go (_:ns) 

我不明白,這兩條線:

 go (n:ns) (match n -> (Just c, g)) = 
      n : go (Graph.neighbors' C++ ns) g 

現在看來,這是定義函數go,它接受一個列表作爲第一個參數,這是通過(n:ns)進行模式匹配。然而,第二個說法我不明白:(match n -> (Just c, g))。這裏的運營商->是什麼意思?通過查看運營商,它可以是以下三件事之一:

  • 函數類型映射運算符。
  • Lambda定義運算符。
  • 分離器在案件建設。

由於沒有case語句,也沒有針對lambda表達式的反斜線轉義變量,所以只能是它是函數類型映射操作符的情況。在這種情況下,我不明白它是如何與這些變量綁定的,cg?它究竟意味着什麼,在爭論中又如何呢?

提前致謝!

回答

7

->在這種情況下既不是函數類型也不是lambda定義也不是case-mapping。這是一個view pattern

go (n:ns) (match n -> (Just c, g)) = 
     n : go (Graph.neighbors' C++ ns) g 

相當於

go (n:ns) g' 
    | (Just c, g) <- match n g' 
     = n : go (Graph.neighbors' C++ ns) g 

其中pattern guard(Just c, g) <- match n g'又簡稱

go (n:ns) g' = case match n g' of 
    (Just c, g) -> n : go (Graph.neighbors' C++ ns) g 
    (Nothing, g) -> ... 

其中Nothing條款需要站在了go定義的後期條款。

2

這是一個view pattern。這個擴展讓我們可以在匹配之前以某種方式改變參數。

沒有這個擴展,代碼必須這樣寫:

go (n:ns) g' = 
    case match n g' of 
    (Just c, g) -> ... 
    ... 

這是更詳細一點。

+0

您需要一個額外的參數,例如'go(n:ns)g'= ...的情況匹配n g'。 – leftaroundabout

+0

@leftaroundabout謝謝,修正:) –

相關問題