GHCi "пусть" - что он делает?
Я был бы признателен, если кто-то может указать на документы о том, что "пусть" делает в GHCi, или, если это не удается, объясните это убедительно:-).
Насколько я могу судить, "пусть" (без "in" ) не является частью языка Haskell как таковой, а с другой стороны, он также не является командой GHCI, поскольку он не префикс двоеточия.
Ответы
Ответ 1
При программировании в GHCi вы, как программирование в IO-монаде с синтаксисом do
, так например, вы можете непосредственно выполнить действие IO
или использовать синтаксис монадического связывания, например r <- someIOFun
.
let
также является частью do
, поэтому вы также можете использовать это. Я думаю, что он был добавлен в let .. in <rest of the computation>
, поэтому, например, когда вы это делаете:
ghci> let a = 1
ghci> someFun
ghci> someFun2
Это нравится:
let a = 1 in
do someFun
someFun2
Ответ 2
Здесь соответствующая часть документации.
Операторы GHCI выполняются как вычисления ввода-вывода. Итак, let
совпадает с тем, что у вас внутри монады IO
, где вы привязываете выражение, отличное от IO, с помощью let
.
Ответ 3
Для получения дополнительной информации о деталях этот комментарий в TcRnDriver.lhs может отображаться:
--------------------------------------------------------------------------
Typechecking Stmts in GHCi
Here is the grand plan, implemented in tcUserStmt
What you type The IO [HValue] that hscStmt returns
------------- ------------------------------------
let pat = expr ==> let pat = expr in return [coerce HVal x, coerce HVal y, ...]
bindings: [x,y,...]
pat <- expr ==> expr >>= \ pat -> return [coerce HVal x, coerce HVal y, ...]
bindings: [x,y,...]
expr (of IO type) ==> expr >>= \ it -> return [coerce HVal it]
[NB: result not printed] bindings: [it]
expr (of non-IO type, ==> let it = expr in print it >> return [coerce HVal it]
result showable) bindings: [it]
expr (of non-IO type,
result not showable) ==> error
Таким образом, команда в приглашении GHCi может иметь до трех эффектов: некоторый код оценивается, некоторые вещи печатаются, а некоторые имена переменных привязаны. Ваш случай (первый в комментарии) связывает переменные, но не печатает.
Синтаксис похож на do-notation, поэтому ответ @sinans несколько прав, но на самом деле это не то, что происходит под капотом - иначе, например, ничто никогда не будет напечатано.
Ответ 4
Команды GHCI выполняются в монаде IO и используют синтаксис do, поэтому применяются правила desugaring. Из Real World Haskell
doNotation4 =
do let val1 = expr1
val2 = expr2
{- ... etc. -}
valN = exprN
act1
act2
{- ... etc. -}
actN
переводит на:
translated4 =
let val1 = expr1
val2 = expr2
{- ... etc. -}
valN = exprN
in do act1
act2
{- ... etc. -}
actN