ghci особый случай для Applicative? - PullRequest
8 голосов
/ 31 октября 2011

В ghci:

λ> :t (pure 1)
(pure 1) :: (Applicative f, Num a) => f a
λ> show (pure 1)

<interactive>:1:1:
    No instance for (Show (f0 a0))
      arising from a use of `show'
    Possible fix: add an instance declaration for (Show (f0 a0))
    In the expression: show (pure 1)
    In an equation for `it': it = show (pure 1)
λ> pure 1
1

Означает ли это, что ghci выполняет Applicative и отображает результат, как IO?

Обратите внимание, что pure () и pure (+1) не делает 'ничего не печатать.

1 Ответ

11 голосов
/ 31 октября 2011

Вы получаете такое же поведение, если используете return вместо pure. Чтобы узнать, что делать, ghci должен выбрать тип для данного выражения. Стандартные правила ghci таковы, что при отсутствии других ограничений он выбирает IO для экземпляра Applicative или Monad. Таким образом, оно интерпретирует pure 1 как выражение типа IO Integer. Выражения типа IO a, введенные в приглашении, выполняются, и их результаты печатаются, если 1. a имеет экземпляр Show и 2. a не (). Таким образом, ввод pure 1 в командной строке приводит к

v <- return (1 :: Integer)
print v
return v

выполняется (и магическая переменная it привязана к возвращенному v). Для pure () применяется особый случай, поскольку () считается неинтересным, поэтому выполняется только return () и it привязывается к (), для pure (+1) возвращается функция, экземпляра Show нет для функций в области видимости, поэтому ничего не печатается. Тем не менее,

Prelude Control.Applicative> :m +Text.Show.Functions
Prelude Control.Applicative Text.Show.Functions> pure (+1)
<function>
it :: Integer -> Integer
Prelude Control.Applicative Text.Show.Functions> it 3
4
it :: Integer

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

...