Can not use spltOn to split String on spaces - haskell

I have a string containing words separated by spaces. I would like to get the individual words.
I verified (in ghci) that the following solution works well:
import Data.String
list_of_words = words "a b c"
but I happened to stumble accross the splitOn function, and since I am still in the basement of Haskell programming, and a curious mind, I wondered whether I could also achieve my goal using this function. Hence I tried:
import Data.List
lw = Data.List.splitOn "a b c"
only to get the error message
Not in scope: ‘Data.List.splitOn’
No module named ‘Data.List’ is imported
I don't understand the first message, but the second one is ridiculous, since I imported the module, and the module name is shown in the ghci prompt. Then I realized that the website above referst to a module Data.List.Split, not Data.List. Hence I tried
import Data.List.Split
only to get the error messages
Could not find module ‘Data.List.Split’
Well, curiosity killed the cat. I should have stayed with my original words solution. But since I opened the box now, could some kind soul explain to me, why my attempts have failed, and how I could have it done correctly?
UPDATE Following the comments to my question, I tried
splitOn " " "a c d"
but this time get the error message
Variable not in scope: splitOn :: [Char] -> [Char] -> t
Perhaps you meant one of these:
‘Text.splitOn’ (imported from Data.Text),
‘splitAt’ (imported from Data.List),
‘Text.splitAt’ (imported from Data.Text)
It looks like Data.Text (which I happened to import too) also has a splitOn function with different signature. Hence, I started a fresh ghci without any imports, and just did a
import Data.List
splitOn " " "a b c"
This gave also the error message
Variable not in scope: splitOn :: [Char] -> [Char] -> t

Install the split library to be able to use it. Since you're a stack user here are the commands for that:
stack build split # install split (some people prefer "stack build" over "stack install", but the difference concerns only executables)
stack ghci # start ghci using the environment of packages installed by stack

Related

Haskell error when using the isNothing function in Maybe

I am trying to use isNothing in my code in Haskell, and it is giving me the error
<interactive>:97:23: error:
• Variable not in scope: isNothing :: Maybe t -> Bool
• Perhaps you meant data constructor ‘Nothing’ (imported from Prelude)
The code line I have is as follows -
maybeMap f value = if isNothing (value) then value else Just (f (check value))
this works fine if I replace isNothing value with value == Nothing, so I am confused why the previous is not working.
First thing's first, the key phrase in the error message is:
Variable not in scope: isNothing
Which means that the compiler just isn't aware of anything named isNothing.
That immediately tells you that the code around your your use of isNothing doesn't matter. It's not a problem with types, or anything to do with the actual isNothing function you're trying to call, and there's no way you can change the code around isNothing to get this to work.
Variable not in scope almost always means one of three things:
You haven't imported the name you're trying to use
You have accidentally misspelled the name you're trying to use
You intended to define something with that name, but haven't done so yet
Changing any of the code surrounding your use of isNothing isn't going to change any of those 3 problems no matter which it is. Even looking at that code isn't going to tell you anything relevant; just closely look at the spelling of the name in the error message to confirm you haven't just made a typo, and if not you know you need to look elsewhere.
In this case it's #1. There are a bunch of useful functions that are in the Haskell Prelude which are automatically imported for you, so you're probably used to just using functions without importing them, but the "normal" case is that to use anything that's already defined you have to import it. isNothing isn't in the Prelude, so that means to use it you have to find out which module it is in and add an import declaration to make it available. (If that module is in a package that isn't already installed, you will also have to obtain the package; that's a question I'm not going to address here)
isNothing comes from the Data.Maybe module (in the base package, which is always installed as part of installing GHC, so no worries there). So you need to use:
import Data.Maybe
If you're working in a file you need to add that to the top of the file (just after the module header, but before you define any names yourself; all imports must come before any of your own code). If you're using the interpreter you can just enter the import as a command.
That will bring all of the names defined in Data.Maybe into scope. If you want more control, you can explicitly import only some of the names, like this:
import Data.Maybe ( isNothing, isJust, listToMaybe )
The function isNothing is not part of the standard prelude. Rather, it's distributed as part of the Data.Maybe module. To use isNothing, you'll need to explicitly import that module:
import Data.Maybe

Split a string by a chosen character in haskell

I'm trying to split a string every time there is a chosen character. So if I receive "1,2,3,4,5", and my chosen character is "," the result is a list such as ["1","2","3","4","5"].
I've been looking through the already answered questions in here and they point me to using splitOn. However, when i try to import Data.List.Split in order to use it, Haskell gives me the following error: Could not find module ‘Data.List.Split’ . When I tried to just use splitOnwithout importing the module, it showed me Variable not in scope: splitOn.
So my questions are,
Is it normal that i'm getting this error? Is splitOn a viable option or should I just try something else?
What other simple solutions are there?
I can just write something that will do this for me but I'm wondering why I'm not able to import Data.List.Split and if there are other simpler options out there that I'm not seeing. Thank you!
If you're using GHC it comes with the standard Prelude and the modules in the base package, and perhaps a few other packages.
Most packages, like the split package (which contains the Data.List.Split module), aren't part of GHC itself. You'll have to import them as an explicit compilation step. This is easiest done with a build tool. Most Haskellers use either Cabal or Stack.
With Stack, for example, you can add the split package to your package.yaml file:
dependencies:
- base >= 4.7 && < 5
- split
You can also load an extra package when you use Stack to start GHCi. This is useful for ad-hoc experiments.
‘Data.List.Split’ is not in prelude and needs to be installed as a dependency package.
Install command depends on environment you are using:
‘stack install split’ for stack
‘cabal install split’ for cabal
Basically this is a foldring job. So you may simply do like
λ> foldr (\c (s:ss) -> if c == ',' then "":s:ss else (c:s):ss) [""] "1,2,3,42,5"
["1","2","3","42","5"]
So;
splitOn x = foldr (\c (s:ss) -> if c == x then "":s:ss else (c:s):ss) [""]
However this will give us reasonable but perhaps not wanted results such as;
λ> splitOn ',' ",1,2,3,42,5,"
["","1","2","3","42","5",""]
In this particular case it might be nice to trim the unwanted characters off of the string in advance. In Haskell though, this functionality i guess conventionally gets the name
dropAround :: (Char -> Bool) -> String -> String
dropAround b = dropWhile b . dropWhileEnd b
λ> dropAround (==',') ",1,2,3,42,5,"
"1,2,3,42,5"
accordingly;
λ> splitOn (',') . dropAround (==',') $ ",1,2,3,42,5,"
["1","2","3","42","5"]

haskell load data from 'script' file

I have been reading "learn you haskell for great good", and in this part:
"let’s put a string that represents a person in a script and then load that script in GHCi:
mysteryDude = "Person { firstName =\"Michael\"" ++
", lastName =\"Diamond\"" ++
", age = 43}"
We wrote our string across several lines like this for increased readability. If we want to read that string, we need to tell Haskell which type we expect in return:
ghci> read mysteryDude :: Person
But I don't know how to create the 'script', it's in mysteryDude.hs file, and then I need to load it with >:l mysteryDude.hs
Or what. But I tried it and I got this error:
*Main> read mysteryDude.hs :: Person
<interactive>:50:23: error:
Not in scope: type constructor or class ‘Person’
*Main> read mysterDude.hs :: Person
I see that in the web here, they change it, and don't do it in the same way, so, maybe it's an error.
But even if in this example is an error I would like to know how to write a 'script' and load data from it.
From comments I deduced the problem. :l in ghci forgets all previous :ls and all definitions that you made in REPL. You should either:
Make files import each other (avoiding import cycles). Filenames and module names must match.
import both files in ghci. Again, module names should match the names of files.
Make all your definitions in REPL's toplevel. You may use multiline snippets surrounding them by :{ :}. Not recommended tho

Haskell: Parse error: module header, import declaration or top-level declaration expected

I am saving some commands in a Haskell script in a .hs file while working thru a Haskell textbook. Here's a small example.
fst (1,2)
snd (1,2)
When I run these commands from the prelude in GHCi, they work fine. When I try to compile the .hs file with these two lines, I get the following:
ch4_test.hs:2:1: error:
Parse error: module header, import declaration
or top-level declaration expected.
|
2 | fst (1,2)
| ^^^^^^^^^
Failed, no modules loaded.
I've googled this error and can't find any explanation what I'm doing wrong.
From a newbie to future newbies: The interactive environment ghci would lead you to believe that you can punch some expressions into an .hs file and run the thing (in a similar fashion to languages like swift and ruby). This is not the case.
Haskell needs an entrypoint called main. Quoting:
Here is a simple program to read and then print a character:
main :: IO ()
main = do c <- getChar
putChar c
The use of the name main is important: main is defined to be the entry point of a Haskell program (similar to the main function in C), and must have an IO type, usually IO ()
Source: https://www.haskell.org/tutorial/io.html
You can't just put any expression in a hs file.
As the error message says, you need a declaration here. For example:
main =
print (fst (1,2)) >>
print (snd (1,2))
I am getting this error but the cause appears to be completely different from anything posted here. And the error message is not at all helpful.
Using Cabal version 3.6.2.0 with GHCI 8.10.7 on MacOS High Sierra (10.13)
I'm working from this page: https://www.tutorialspoint.com/haskell/haskell_modules.htm
specifically the "custom modules" section. There you can see the code I copied and pasted.
Besides the tutorial not mentioning I needed to add "other-modules: Custom" to myfirstapp.cabal, and besides the fact that the sample Custom.hs file includes "if x 'rem' 2 == 0" rather than "if x rem 2 == 0", here is the problem:
Indentation matters!
This line (inside the quotes) does NOT work "if x rem 2 == 0".
This line DOES work " if x rem 2 == 0"!
Indenting by one space is the difference between success and failure.
I'm totally new to Haskell. I've programmed extensively in PHP, Javascript, and Applescript, and dabbled in a dozen others, and this is the first time I've seen white space matter. I assume this is commonly known amongst Haskell veterans, but it would certainly be nice if that was included prominently in the documentation.

Using Emoji in Haskell

I've recently come across a bot on Twitter named EmojiHaskell, that claims to tweet 'interpretable Haskell code with emoji variable names'. A particular Tweet caught my attention, as it looked like malformed syntax to me, so I decided to take a closer look. So far I've produced the following code:
module Main where
🙏 :: [🍳] -> Maybe 🍳
🙏 [] = Nothing
🙏 (👽:as) = Just 👽
main = print $ 🙏 "♥"
Since I've used λ on occasion in my Haskell code, I expected this code to work, but it appears that GHC doesn't like the emoji at all.
With $ runhaskell Main.hs I get:
Main.hs:4:1: parse error on input ‘🙏’
I've already had a look at the UnicodeSyntax extension,
and tried to only use some or single emoji instead of all of them to see if a certain one provokes the problem.
Now my question is this:
Is there currently a Haskell compiler that would accept the code?
Can I get GHC to work with this code somehow?
That code is not valid haskell. The reason is that 🙏 (like, probably, all Emojis) is a symbol character:
Prelude> import Data.Char
Prelude Data.Char> generalCategory '🙏'
OtherSymbol
But you can still use them like any other symbol, namely as an operator:
Prelude Data.Char> let (🙏) = (+)
Prelude Data.Char> 32 🙏 42
74
Furthermore, as user3237465 pointed out, if you use the prefix syntax for operators, i.e. put it in parentheses, you can even use it like any other symbol:
(🙏) :: [a] -> Maybe a
(🙏) [] = Nothing
(🙏) ((👽):as) = Just (👽)
main = print $ (🙏) "♥"
This is almost the example in the original post. Unfortunately, this trick does not work for the type variable. The the documentation is worded a bit unfortunately, but in fact symbols are never type variables and always type constructors

Resources