Я учусь mtl
библиотека и пытающийся сделать некоторый мой собственный MonadTransformers. Я проверял Control.Monad.State.StateT
объявление, и через весь код, я вижу этот синтаксис:
execStateT :: (Monad m) => StateT s m a -> s -> m s
execStateT m s = do
~(_, s') <- runStateT m s
return s'
Что делает это ~
средний операнд?
Это обозначение ленивого шаблона в Haskell. Не могу сказать, что я знаком с ним, но отсюда :
Это называется ленивым шаблоном и имеет форму ~ pat. Ленивые шаблоны неопровержимы: сопоставление значения v с ~ pat всегда удается, независимо от pat. С оперативной точки зрения , если идентификатор в pat позже "используется" с правой стороны, он будет привязан к той части значение, которое получилось бы, если бы v было для успешного соответствия pat, и ⊥ в противном случае.
Кроме того, этот раздел может быть полезен.
Это эквивалентно
execStateT m s = do
r <- runStateT m s
return (snd r)
или
execStateT m s =
runStateT m s >>= return . snd
Для нормального сопоставления с шаблоном необходимо оценить значение, которое должно быть сопоставлено, чтобы его можно было сравнить с шаблоном.
~
обозначает ленивое сопоставление с образцом: просто предполагается, что значение будет соответствовать образцу. Тогда сопоставление выполняется только позже, если фактически используется значение сопоставленной переменной.