Haskell: Not in scope: foldl'? - haskell

As my first module experience, I imported Data.List to my GHCi. (More precisely, I typed import Data.List on my GHCi) It seems to be working fine because I can use some functions that I did not have before such as foldl' on my GHCi.
I wrote haha = foldl' (+) 0 [1..10] on my notepad++, and saved it and loaded then GHCi says Not in scope: foldl' even though it workds just fine when I type foldl' (+) 0 [1..10] directly on my GHCi.
Why is that and how can I define functions with foldl' on my notepad?

What's in scope at the GHCi prompt is not necessarily the same as what's in scope in whatever file you may be loading from GHCi. GHCi has its own notion of current scope, which usually includes the toplevel of whatever file you've loaded plus any other modules you explicitly add or anything you import. (It also behaves differently if loading a file that hasn't been changed since it was last compiled, which still confuses me...)
Anyway, you just need to import Data.List in the code file itself, e.g.:
module Main where
import Data.List
haha = foldl' (+) 0 [1..10]
After doing that, loading the file should result in Data.List being effectively imported at the GHCi prompt as well, since it's visible at the toplevel of the loaded module.

Related

Should I avoid using interactive mode?

Haskell newbie here. I use ghci to implement a baby quicksort algorithm [1] as follows:
Prelude> quicksort (firstx:xs) = quicksort[x|x<-xs, x<firstx] ++ [firstx] ++ quicksort[x|x<-xs, not(x<firstx)]
Prelude> quicksort [] = []
The command quicksort [1,2,3] then gives an error:
*** Exception: :8:1-17: Non-exhaustive patterns in function quicksort
However, typing the exact same thing in an quicksort.hs file and running $ ghci quicksort.hs do not yield such an error.
Question
What makes the difference? Is it a rule of thumb that one should avoid using interactive mode?
Reference
[1] Rex Page. Two Dozen Short Lessons in Haskell
It's generally easier to define a multi-line function in a file and then load :l <module> or reload :r, but I do sometimes declare a multi-line function directly in GHCi starting with :{ and :}:
:{
quicksort (firstx:xs) = quicksort[x|x<-xs, x<firstx] ++ [firstx] ++ quicksort[x|x<-xs, not(x<firstx)]
quicksort [] = []
:}
:h is useful if you forget any commands while in GHCi.
Edit: forget to address the second part of your question.
Is it a rule of thumb that one should avoid using interactive mode?
Interactive mode is a great tool and I miss it in other ecosystems like ReasonML that do not have one. There is no reason to avoid it. Just remember to copy your code over if you come up with some that you want to keep.

Compiled vs Interpreted: To Let or Not To Let

Why does the Haskell interpreter (GHCI 7.10.3) need function definitions to be in a let expression, but the Haskell compiler (GHC 7.10.3) throws a parser error if a function definition is within a let expression?
I'm working through "Learn You a Haskell for Great Good!" Baby's first function is doubleMe:
doubleMe x = x + x
Why does the interpreter accept this definition if it is within a let expression and otherwise throw a parse error on input '='? Meanwhile, if I'm compiling the same function from a file, why does GHC throw a parse error if the function definition is within a let expression and compiles the definition if it is not within a let expression? Coming from a Lisp background, I'm surprised that interactive Haskell and file loading and compilation Haskell treats these definitions differently.
The reasoning behind this is that GHCi (in 7.10.3) expects at the prompt only
commands (type in :h to list the commands available)
declarations (things like data, type, newtype, class, instance, deriving, and foreign but not a regular definition)
imports
expressions (things like 1+1 or let x = 3 in x*x)
I/O Actions / do statments (things like print "hi" or x <- getLine OR let doubleMe x = x + x)
If this seems surprising to you, remember that the evaluation of Lisp and Haskell is very different - Lisp just gets interpretted, while Haskell is being compiled.
As you can tell, top-level definitions are not part of this list. Thankfully this got fixed in GHCi 8.0.1, which now supports raw top-level function declarations. The following works (in 8.0.1):
ghci> doubleMe x = x + x
ghci> doubleMe 1
2
The GHCi interpreter command line treats its input as if it were in a do clause. So you can type this:
:module + System.Random
v <- getStdRandom $ randomR (1,10)
Apart from the :module directive this is exactly how it would be in a do clause.
Likewise you can write
let f x = 2 * x
because that is how it would be in a do clause.
Modern Lisp implementations compile to native code, often by default even when code is entered at the prompt. Lisp's prompt isn't just a place to enter commands, it's a place to interact with the language because the entire language is made available by the Read-Evaluate-Print Loop. This means that Lisp reads the text into symbolic expressions, which it then evaluates, printing any print output and any returned values. For example,
? (defun a-fun () nil)
A-FUN
? (compiled-function-p #'a-fun)
T
Compiled-Function-P
Clozure Common Lisp
With Lisp, code you can enter into the Lisp image by compiling and loading a file you can also enter into the Lisp image by typing it out at the REPL. So it turns out I was surprised because I was expecting the GHCi prompt to be a REPL, but as #Alec describes it's not because it doesn't read text into Haskell expressions that it would then evaluate, as Lisp does. As #dfeuer says, the issue isn't about compilation versus interpretation. The issue is that GHCi's prompt offers limited interaction with a Haskell compiler, rather than interaction with Haskell itself as Lisp's REPL does.

GHCI vs Prelude command prompt in Haskell

I am trying to learn Haskell from the beginning and was wondering what exactly is the difference between the two prompts (Haskell and Prelude) that are used in it. It may sound a very naive question and not to mention I tried searching for the answer before posting this question but couldn't find one (proper one). Thank you in advance.
Okay, if I'm understanding this correctly, you're wondering if there's a difference between
Prelude>
and
ghci>
as prompts after you've invoked GHCi from the command line.
If this is the case, then there is no real difference aside from preference. You can change the prompt to whatever you want to by using the command:
:set prompt "aglebargle> "
You can replace arglebargle> with whatever you'd like.
The main advantage I see for the Prelude> prompt is that it will update when you import modules. Prelude is the only module you have without any imports, which is why it's the prompt. E.g., if you, say, did import Control.Monad, you'd get Prelude Control.Monad> as a prompt.
The prompt indicates which module(s) is being worked on and since the Prelude is a standard module for Haskell from GHC it is shown explicitly as the first prompt. However from GHC version 9.x the Prelude is loaded implicitly (unless some directive to the contrary has been given) so the prompt from now on is just "ghci>".
By the way, the Prelude module contains a set of basic types, type classes, and functions to use at the start of any Haskell project without needing to define everything from the beginning.

Find inferred type for local function

Is there a way in ghci (or ghc) to find what the inferred type of a local function is?
E.g. if I have a function
f l = map f' l
where f' = (+1)
is there a :t-like way in ghci to see what the inferred type for f' is?
Indeed there is, which I learned about thanks to hammar's awesome answere here. Here's the short version:
Prelude> :l /tmp/foo.hs
[1 of 1] Compiling Main ( /tmp/foo.hs, interpreted )
Ok, modules loaded: Main.
*Main> :break f
Breakpoint 0 activated at /tmp/foo.hs:(1,1)-(2,18)
*Main> f [1..10]
Stopped at /tmp/foo.hs:(1,1)-(2,18)
_result :: [b] = _
[/tmp/foo.hs:(1,1)-(2,18)] *Main> :step
Stopped at /tmp/foo.hs:1:7-14
_result :: [b] = _
f' :: b -> b = _
l :: [b] = _
[/tmp/foo.hs:1:7-14] *Main> :t f'
f' :: b -> b
I don't know of any way of doing it from GHCi.
However, if you're using an editor like Emacs or Vim, you can try ghc-mod. This is an external tool that plugs into an editor and gives you some IDE-like functionality for Haskell programs, including the ability to get the type of an arbitrary expression, including a local definition.
In Emacs, you would use C-c C-t to find the type of an expression.
If you're not using Emacs or Vim, you could probably wrap ghc-mod as a GHCi extension or something, but I think that would be somewhat awkward. I can't imagine a good way to do it without having an editor-like UI. However, ghc-mod itself is just a standalone command-line tool, so it's easy to work with. If you can think of a good user interface for it that's independent of an existing text editor, go for it!
Of course, if you're not using Emacs or Vim, you probably should :P.
Try hdevtools, it's quite fast and easy to use, though there's only integration for Vim.

GHCi usage question

I am studying Haskell and use Emacs+Haskell mode as my editor.
After playing some simple expressions in GHCi, I am wondering whether these IDE/editor functionality that exist in Visual Stuido for F#:
Can I send the content in the clipboard into the interpreter? Currently I can only :load the file into the interpreter. This is inconvienent when I gradually write functions in a script file. Like 'Alt+Enter' in visual stuido.
After compiling, I hope to see the signature of the function, e.g.
let double x = x + x
so that I can better understand the type inference mechanism in Haskell.
On Windows, there's WinGHCi, a gui including (poor, but often sufficient) support for copy and paste. Dunno about the command line version.
Use :type double (or the shortcut :t double) to get the type signature of double. There's also :info which applies to values (including functions) as well as types and typeclasses (e.g. :info Bool lists the definition of Bool and all typeclasses it is an instance of) and says where it was defined.
Regarding question 2, to see the inferred type of an expression every time you type one in, you can give inside ghci :set +t . I think you could also put that in a .ghci file, inside your home directory, as described in http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/ghci-dot-files.html .
As far as I know, there is no support for sending the clipoards to the interpreter "out of the box", but it should not take more than couple of lines of elisp. I'd look in the support modes for other languages and copied it from there if I were you.
Regarding the types, you could type C-c C-t or C-c C-i on any symbol in your code, which would trigger ":t <symbol>" and ":i <symbol>" commands in the ghci process
TAIM claims to send selected expressions in vim to ghci(haven't tried it)
I'm not sure about function signatures inside the editor but in ghci its ":t func"
Actually looking at their youtube video it looks like TAIM may be able to select ":t func" in vim and send it to interpreter.

Resources