Почему нет аргумента? С аргументом отдадим, что нам помешает?
Ну а если есть, будет применена, да, просто вы написали «функцию», и проще было понять как просто голую функцию, а не применение её к чему-то.
Что вы понимаете под словом "зафорсится"? Обычно это означает принудительное выполнение, то есть вариант без лени, но в дальнейшем тексте вы несколько по другому используете это слово.
Принудительное вычисление, чтобы thunk превратился во что-то в слабой головной нормальной форме (WHNF).
Поэтому слева стоит вывод в консоль (ибо его должно быть видно), который не происходит, что означает - принудительного исполнения не было, как не было и ленивого исполнения (отсроченного), потому что никто не позвал данное вычисление.
Было, что можно проверить кодом
(undefined :: IO ()) `seq` 1 —
undefined вычислится и даст как полагается исключение. Я привёл его здесь к типу
IO (), чтобы не возникало соблазна сказать, что
IO a обрабатываются
seq специальным образом.
На чём основывается такое мнение? Даже теоретически - зачем нужен какой-то там фейковый объект, если у рантайма в распоряжении есть сам рантайм? Чего ему не хватит? У него и так всё есть.
Как я уже написал, в подходе, использующем
RealWorld, без него нельзя, по определению. В каком-то другом подходе можно обойтись без
RealWorld вообще. Важно не это, важно что мы можем или не можем делать; сначала в этой теме решили показать, почему мы не можем делать что-то, взяв для иллюстрации этот подход. Но он не обязателен, просто если не лезть в реализацию
IO, будет и нечем иллюстрировать вам, почему вы должны быть неправы. Можно, конечно, не пытаться ничего иллюстрировать, просто люди попались достаточно добрые.
Вот здесь непонятен смысл слова "форсим". Оно принуждает или?
Принуждает, но пока вы не начнёте смотреть детали, вы, вероятно, не разберётесь, почему получается то, что вам кажется отсутствием принуждения. Ещё можно например почитать, почему
seq оказывается иногда мало и для чего придумали
deepseq.
В обычном понимании принуждения мы принуждаем рантайм выполнить любую операцию, которую считаем обязательной к мгновенному исполнению.
Уверен, что в упомянутом вами Haskell Report 2010 вот так не написано, а написано конкретнее (по идее про WHNF должно быть сказано).
Вот опять - принуждение должно приводить к мгновенному исполнению, а вы говорите об отложенном исполнении. Поэтому я не понимаю смысла слова "форсить".
Ну в принципе тут может быть непонимание, если позволить
IO a быть просто банально обёрткой над
a (но никто вроде так не делает).
Тогда если бы мы зафорсили некое значение
IO a, его эффекты бы выполнились.
Работ с эффектами скрыта в IO, которое, возможно, как-то по своему воспринимает необходимость исполнения.
Само по себе оно никак не воспринимает, в том и дело. Насколько я в курсе, никакой подход к функциональному вводу-выводу не использует изменений в стратегии вычисления именно для него.
Ещё раз, в наивном понимании значение типа
IO a — это лишь
описание того, что надо сделать, и что должно вернуть
a, если не будет исключений. Зафорсим мы выражение, дающее такое описание в результате — разумеется, ничего не будет выполнено волшебным образом. Мы просто получим описание в WHNF (то есть даже не полностью до всех-всех конструкторов развёрнутое). Почему вы это игнорируете, непонятно. Если же вам не нравится аргумент от наивного описания, то надо поднять уровень разговора и говорить в любом случае более специфично.
Мне кажется, это не проблема монад или апликативов, а проблема хаскеля. Банально - он плохо документирован.
Это уход в сторону.
Очень надеюсь, что вы делаете такое раз за разом не сознательно.
При этом Haskel Report даёт лишь намёки, но никакой конкретики, ссылаясь на свободу реализации, поэтому нужно изучать реальное устройство компилятора, которых несколько, что очевидно - несколько кривой подход.
Понимается ли под устройством документация? В том числе документация к стандартным пакетам. (Но вообще я не хочу развивать это ответвление, так можно до бесконечности, а тема вообще изначально не про IO хаскеля и не про его документацию.)