GHCi пусть что делает?

Я был бы признателен, если бы кто-нибудь мог указать на документы о том, что let делает в GHCi, или, если это не так, убедительно объяснить это.

Насколько я могу судить, let (без in) не является частью языка Haskell как таковой, и, с другой стороны, это также не команда GHCi, поскольку перед ней не стоит двоеточие.


person gwideman    schedule 27.12.2012    source источник
comment
Краткий ответ: let (без in) является частью языка Haskell, когда находится внутри блока do (и запись в GHCi напоминает запись в монаде IO).   -  person MasterMastic    schedule 09.03.2015


Ответы (4)


При программировании в 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
person sinan    schedule 27.12.2012
comment
Это не просто IO (), а любое IO действие типа IO a. - person Satvik; 27.12.2012
comment
ОК, это имеет смысл, и связывает GHCi пусть с Haskell пусть... in do. - person gwideman; 27.12.2012
comment
let без in допускается в блоке выполнения и не эквивалентен приведенному вами примеру (см. stackoverflow.com/questions/8274650/) - person SwiftsNamesake; 05.03.2017
comment
Это обессахароженное слово меня на некоторое время сбило с толку. Думал, что это было des-u-gared. Понятия не имел, что это значит. - person jmrah; 27.07.2018

Вот соответствующая часть документации. .

Операторы GHCI выполняются как вычисления ввода-вывода. Таким образом, let совпадает с тем, что у вас есть внутри монады IO, где вы связываете выражение, отличное от ввода-вывода, с помощью let.

person Satvik    schedule 27.12.2012
comment
Спасибо за указание на документы, я этого не нашел. В качестве побочного комментария этот документ довольно разочаровывает, поскольку его объяснение let основано на понимании монад. Новые пользователи почти сразу же сталкиваются с let, так как он часто представлен в руководствах по начальным понятиям Haskell, но он не работает, если скопировать его в исходный файл haskell, а объяснения, предполагающие понимание монад, не слишком полезны. Тем не менее, с коллекцией ответов здесь я, по крайней мере, вижу, как эти функции сочетаются друг с другом. - person gwideman; 27.12.2012
comment
@gwideman Да, я понимаю. Вы не можете напрямую скопировать то, что вы пишете как операторы ghci в файле hs, и ожидать, что они будут работать. Ну, вы, конечно, можете сделать main = do <your ghci statements>. Это может не всегда работать так, как ожидается, поскольку ghci печатает вывод оператора, используя свой экземпляр Show. - person Satvik; 27.12.2012

Более подробные сведения о коде см. в этом комментарии в 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-нотацию, поэтому ответ @sinan в чем-то прав, но на самом деле это не то, что происходит под капотом — иначе, например, ничего бы никогда не было напечатано.

person Joachim Breitner    schedule 27.12.2012
comment
Я почти уверен, что не понимаю всего этого на данном этапе, но очень полезно увидеть, в какой степени не следует учиться у GHCi :-). Спасибо! - person gwideman; 28.12.2012

Команды GHCI выполняются в монаде IO и используют синтаксис do, поэтому применяются правила дешугаринга. Из 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
person Boris    schedule 27.12.2012
comment
Хорошо, это имеет большой смысл. - person gwideman; 27.12.2012