Требуется ли ограничение Monad в <$!> ` - PullRequest
4 голосов
/ 27 мая 2020

Как заявлено в документации , <$!> - это строгая версия <$>, но на удивление

<$!> :: Monad m => (a -> b) -> m a -> m b 
f <$!> m = do
  x <- m
  let z = f x
  z `seq` return z

вместо более естественной ( на мой взгляд; потому что он сохраняет более слабое ограничение и имитирует $!)

<$!> :: Functor f => (a -> b) -> f a -> f b
f <$!> x = x `seq` (f <$> x)

Я предполагаю, что применение seq после привязки отличается от «естественного» подхода, но я не знаю, как это другое. Мой вопрос: есть ли причина, по которой "естественный" подход становится бесполезным, и почему реализация ограничена Monad?

Ответы [ 2 ]

4 голосов
/ 27 мая 2020

GH C s сообщение фиксации включает следующие две ссылки, которые проливают больше света на эту функцию:

Это была причина, о которой говорит Йохан Тибелл (цитата из связанного списка рассылки):

Он работает с монадами вместо функторов, как того требует мы при проверке аргумента.

Эта версия очень удобна, если вы хотите работать с функторами / аппликативами, например, в синтаксическом анализаторе и в то же время избегать ложных переходов. Я понял, что это было необходимо при устранении проблем с большим использованием пространства (но не с утечкой пространства) в маниоке.

2 голосов
/ 27 мая 2020

Я предполагаю, что применение seq после привязки отличается от «естественного» подхода, но я не знаю, насколько он отличается.

Поскольку haskell работает, seq должен работать через зависимости данных; он устанавливает связь: «когда seq x y оценивается как WHNF, a также будет».

Идея здесь состоит в том, чтобы привязать оценку a к внешнему m a которые, как мы знаем, должны быть оценены для каждого >>= или <*>, чтобы продолжить.

В вашей версии:

Prelude> f <$!> x = x `seq` (f <$> x)
Prelude> let thunk = error "explode"
Prelude> case (+) <$!> Just thunk <*> Just thunk of ; Just _ -> "we can easily build up thunks"
"we can easily build up thunks"

Мне интересно, возможно ли лучшее решение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...