5

I have defined the following function (taken from http://www.happylearnhaskelltutorial.com/1/shop_for_food_with_list.html#s9) on an emacs file:

firstOnesOrEmpty :: [String] -> String
firstOnesOrEmpty [] = ""
firstOnesOrEmpty [x] = x
firstOnesOrEmpty (x:y:_) = x ++ ", " ++ y

But when I load my file onto GHCi and write :t firstOnesOrEmpty into GHCi, I get the following error:

<interactive>:1:1: error: Variable not in scope: firstOnesOrEmpty 

What is going wrong?

I also have a similar problem with another function defined on my emacs file (again from the website above):

joinedWithCommas :: [String] -> String
joinedWithCommas []     = ""
joinedWithCommas [x]    = x
joinedWithCommas (x:xs) = x ++ ", " ++ joinedWithCommas xs

Trying to use this function in GHCi I get:

  "ghci>" joinedWithCommas [] 

  <interactive>:40:1: error:
  Variable not in scope: joinedWithCommas :: [a0] -> t
  "ghci>" joinedWithCommas [x] 

  <interactive>:41:1: error:
  Variable not in scope: joinedWithCommas :: [a0] -> t

  <interactive>:41:19: error: Variable not in scope: x
  "ghci>" joinedWithCommas ["x"] 

  <interactive>:42:1: error:
  Variable not in scope: joinedWithCommas :: [[Char]] -> t

I hope someone can help.

I have looked at previous answers to questions on this topic, and am unable to see how they provide answers to my question.

If someone could point me in the direction of a previous relevant answer and explain how that answer actually answers my question (which I repeat, is not clear to me), I would be extremely grateful.

user65526
  • 685
  • 6
  • 19
  • 1
    I can't reproduce the error when loading the function from a file. How are you loading the file? – chepner Mar 13 '18 at 14:45
  • By using `:l experiment`, where the emacs file is named experiment.hs – user65526 Mar 13 '18 at 14:46
  • Which GHC version is it? Did you export the function? – wisn Mar 13 '18 at 14:47
  • Unless you have a typo that doesn't appear in your question, I don't see how you could get that error. – chepner Mar 13 '18 at 14:48
  • 3
    Version 8.2.2, WinGHCi. Also the file is experiment.hs~ I looked at the file's properties, and it is marked as HS~ File (.hs~). Perhaps it has to do with the type of file I saved? – user65526 Mar 13 '18 at 14:50
  • I would expect any problem specific to file metadata to occur immediately with the `:l experiment` command. – chepner Mar 13 '18 at 14:52
  • Have you actually written your file? `.hs~` is an emacs temporary backup file, not the "actual" file. – Cubic Mar 13 '18 at 14:53
  • The problem was the status of the emacs file. I looked at the file and the emacs file did not have the Haskell logo on it, whereas another file did. I looked at the file's properties, and they were listed as HS~ File (.hs~) instead of Haskell Source File (.hs). Also, the file was listed as opening with "Windows Shell Common Dll" instead of with "GHCi" – user65526 Mar 13 '18 at 14:56
  • Yes, I didn't realise this. So I conclude (!) something obvious to most people au fait with these sorts of things that temporary backup files cannot be loaded onto GHCi. :) – user65526 Mar 13 '18 at 14:57
  • And `:l experiment` didn't give any indication that it didn't actually load the file? Regardless of the extension, the *contents* of the file are identical; I would expect GHCi to either load the file fine or complain that the file is invalid. – chepner Mar 13 '18 at 14:58
  • `:l experiment' loaded perfectly, with "ghci>" :l experiment [1 of 1] Compiling Main ( experiment.hs, interpreted ) Perhaps because of the bona fide file `experiment.hs` which I had – user65526 Mar 13 '18 at 15:04
  • @chepner Thanks for undoing my duplicate closure. I got overconfident about it after looking at your answer, not realising the oddness of the issue as described by the OP. – duplode Mar 13 '18 at 15:22
  • @duplode That fact that I *could* do it surprised me; I didn't realize until that moment that I'd earned the gold `haskell` badge. – chepner Mar 13 '18 at 15:26
  • (@chepner Looks like you earned it this Friday... Congratulations! :)) – duplode Mar 13 '18 at 15:48

1 Answers1

9

To type a multiline definition in GHCi, you need to enclose it in :{...:}

Prelude> :{
Prelude| joinedWithCommas :: [String] -> String
Prelude| joinedWithCommas []     = ""
Prelude| joinedWithCommas [x]    = x
Prelude| joinedWithCommas (x:xs) = x ++ ", " ++ joinedWithCommas xs
Prelude| :}
Prelude> joinedWithCommas []
""

Otherwise, each line is processed in isolation.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • But I want to have the function defined in my emacs file and then load it onto GHCi. Do I have to enclose the function in `:{...:}` on my emacs file, in order to do this? – user65526 Mar 13 '18 at 14:42
  • This explains the errors in the second half of your post. I can't reproduce the problem loading from a file; can you provide more information in the question about how you load it? – chepner Mar 13 '18 at 14:47
  • By using `:l experiment`, where the emacs file is named experiment.hs~. – user65526 Mar 13 '18 at 14:51
  • 1
    I discovered the problem. It was the status of the emacs file. I looked at the file and the emacs file did not have the Haskell logo on it, whereas another file did. I looked at the file's properties, and they were listed as HS~ File (.hs~) instead of Haskell Source File (.hs). Also, the file was listed as opening with "Windows Shell Common Dll" instead of with "GHCi" – user65526 Mar 13 '18 at 14:56