2016-09-11 18 views
12

我一直在尋找一些Haskell的源代碼,並與!_跨越模式匹配來了,代碼是在這裏:http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.List.html#unsafeTake什麼時候在Haskell中使用「嚴格通配符」有用?它有什麼作用?

take n xs | 0 < n  = unsafeTake n xs 
      | otherwise = [] 

-- A version of take that takes the whole list if it's given an argument less 
-- than 1. 
{-# NOINLINE [1] unsafeTake #-} 
unsafeTake :: Int -> [a] -> [a] 
unsafeTake !_ []  = [] 
unsafeTake 1 (x: _) = [x] 
unsafeTake m (x:xs) = x : unsafeTake (m - 1) xs 

我真的不明白「嚴格通配符」是如何工作的,以及爲什麼它是有用此功能(或任何其他功能)。

回答

12

的想法是,unsafeTake(和take爲此事),當被要求返回空列表的第一個元素m,它應該返回一個空列表,不管是什麼的m值。但是,如果m是引發異常的表達式呢?例如,unsafeTake undefined []返回[]會很奇怪。所以我們需要確保m的計算結果爲整數,即使我們不關心它的確切值(當然是空列表的情況)。這使得unsafeTake的行爲方式與第一個參數相同,不管第二個參數(列表)是否爲空。

+1

我想值得一提的是,如果使用'undefined'作爲'n'參數的'take'函數,那麼它不太可能在'unsafeTake'函數中發現錯誤,因爲'n'與之前的零比較,先評估一下。但是因爲'take'函數應該儘可能內聯(如註釋所示),所以在進行一些優化之後,這個檢查可能會消失。這就是爲什麼我們需要在'unsafeTake'中使用'!''的原因。 – Shersh

相關問題