Подтвердить что ты не робот

Когда полезно использовать "строгий шаблон" в Haskell и что он делает?

Я смотрел на некоторый исходный код Haskell и наткнулся на совпадение с шаблоном !_, код здесь: http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.List.html#unsafeTake

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

-- A version of take that takes the whole list if it 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

Я действительно не понимаю, как работает "строгий шаблон" и почему он полезен для этой функции (или любой другой функции).

4b9b3361

Ответ 1

Идея состоит в том, что unsafeTaketake, если на то пошло), когда его попросят вернуть первые m элементы пустого списка, он должен вернуть пустой список, независимо от того, что значение m есть. Но что, если m - выражение, которое выдает исключение? Например, для unsafeTake undefined [] было бы странно возвращать []. Поэтому нам нужно убедиться, что m оценивается как целое, даже если нам все равно, что его точное значение (для случая с пустым списком, конечно). Это заставляет unsafeTake вести себя одинаково, когда дело доходит до его первого аргумента, неважно, является ли второй аргумент (список) пустым или нет.