Почему импорт Control.Applicative позволяет этому плохому коду выполнять проверку типов?

Я помогаю своему другу изучать Haskell, и он недавно создал подобный код, который проверяет тип и создает цикл, загружающий ЦП во время выполнения. Я совершенно сбит с толку этим.

import Control.Monad
import Control.Applicative

main = forever putStrLn "Hello, infinity"

Это не должно проверять тип, но делает. Правильная версия, очевидно, будет следующей:

main = forever $ putStrLn "Hello, infinity"

Что для меня странно и удивительно, так это то, что вы получаете разные результаты с импортом Control.Applicative и без него. Без импорта он не проверяет тип:

Prelude Control.Monad> forever putStrLn "Hello, infinity"

<interactive>:1:1:
    No instance for (Monad ((->) String))
      arising from a use of `forever'
    Possible fix: add an instance declaration for (Monad ((->) String))
    In the expression: forever putStrLn "Hello, infinity"
    In an equation for `it': it = forever putStrLn "Hello, infinity"

Я не вижу экземпляр Monad для ((->) Stringв источнике для Control.Applicative, так что я предполагаю что-то странное происходит из-за использования Control.Category или Control.Arrow, но я не знаю. Поэтому у меня есть два вопроса:

  1. Что такого в импорте Control.Applicative, что позволяет этому происходить?
  2. Что такое происходит, когда он входит в бесконечный цикл? Что Haskell на самом деле пытается выполнить в этом случае?

Спасибо,

10
задан Daniel Lyons 17 March 2012 в 20:20
поделиться