Why is Haskell complaining about this plus sign? - haskell

From this code intended to convert a balanced ternary representation to a Haskell Integer:
frombal3 :: String -> Integer
frombal3 "+" = 1
frombal3 "0" = 0
frombal3 "-" = -1
frombal3 current:therest = \
(*) frombal3 current (^) 3 length therest \
+ frombal3 therest
I got the error:
main.hs:7:3: error: parse error on input ‘+’
|
7 | + frombal3 therest
| ^
<interactive>:3:1: error:
• Variable not in scope: main
• Perhaps you meant ‘min’ (imported from Prelude)

It is not clear what you are trying to achieve, but I can see some mistakes that can be already pointed out.
Problems
You don't need \ to continue a line, that's only needed inside strings. Indentation is enough in Haskell
You need to wrap your pattern matching with parenthesis: (current:therest). Furthermore, this pattern will make current a Char and not a String, so you cannot directly pass it to your function that takes a String.
You need to wrap your function arguments as well: if you want to multiply frombal3 current by 3, you need (*) (frombal3 current) 3, or the much better frombal3 current * 3. Infix functions have higher precedence and make the code more clear.
Suggestions
I am not sure what you want to achieve, but this looks like somthing that can be done with a fold or simple list comprehension

Don't use backslashes, and remember to properly bracket pattern matches:
frombal3 :: String -> Integer
frombal3 "+" = 1
frombal3 "0" = 0
frombal3 "-" = -1
frombal3 (current:therest) = -- ^ Note brackets
(*) frombal3 current (^) 3 length therest
+ frombal3 therest
This still causes a problem due to how you're using operators, but I think you can solve this on your own, especially since I can't work out what you're trying to do here.

You appear to be trying to use backslashes to continue onto the next line; don't do that. If you just delete all the backslashes, the error will go away. (You'll get several other errors, but this particular one will go away.)
Haskell uses indentation to detect where one part ends and the next begins. You don't need to manually add backslashes to the end of each line to continue an expression.

Related

How to deal with file ending '\' in strings haskell

import Data.Char (isAlpha)
import Data.List (elemIndex)
import Data.Maybe (fromJust)
helper = ['a'..'z'] ++ ['a'..'z'] ++ ['A'..'Z'] ++ ['A'..'Z']
rotate :: Char -> Char
rotate x | '\' = '\'
|isAlpha(x) = helper !! (fromJust (elemIndex x helper) + 13)
| otherwise = x
rot13 :: String -> String
rot13 "" = ""
rot13 s = map rotate s
main = do
print $ rot13( "Hey fellow warriors" )
print $ rot13( "This is a test")
print $ rot13( "This is another test" )
print $ rot13("\604099\159558\705559&\546452\390142")
n <- getLine
print $ rot13( show n)
This is my code for ROT13 and there is an error when I try to pass file ending directly
rot13.hs:8:15: error:
lexical error in string/character literal at character ' '
|
8 | rotate x | '\' = '\'
There is also an error even from if not replace just use isAlpha to filter
How to deal with this?
As in many languages, backslash is the escape character. It's used to introduce characters that are hard or impossible to include in strings in other ways. For example, strings can't span multiple lines*, so it's impossible to include a literal newline in a string literal; and double-quotes end the string, so it's normally impossible to include a double quote in a string literal. The \n and \" escapes, respectively, covers those:
> putStrLn "before\nmiddle\"after"
before
middle"after
>
Since \ introduces escape codes, it always expects to be followed by something. If you want a literal backslash to be included at that spot, you can use a second backslash. For example:
> putStrLn "before\\after"
before\after
>
The Report, Section 2.6 is the final word on what escapes are available and what they mean.
Literal characters have a similar (though not quite identical) collection of escapes to strings. So the fix to your syntax looks like this:
rotate x | '\\' = '\\'
This will let your code parse, though there are further errors to fix once you get past that.
* Yes, yes, string gaps. I know. Doesn't actually change the point, since the newline in the gap isn't included in the resulting string.

How to compare string to value without quotation marks

I am pretty new to Haskell and today I was trying to make a calculator using Haskell (like most people make when learning a new language to get the hold of if statements) and I had trouble using if values with strings. I want to check if the string the user wrote is "plus" (without "") but if I don't the quotation marks (so it'd look like if op == plus) it doesn't recognize it as a string and outputs an error but if on the other hand I use the quotation marks (so it'd look like this if op == "plus") then it looks for the string "plus" with the quotation marks, how can I compare a string to a value without quotation marks?
Case 1:
calculate x op y = do
if op == "plus"
then x+y
else x
Result: the program looks for "plus" when calling the function and thus if the input when calling the function is for example "1 plus 3" it will give out an error of ':67:13: error: Variable not in scope: plus :: [Char]
Case 2:
calculate x op y = do
if op == plus
then x+y
else x
Result: When trying to load the program I get the error "test.hs:2:33: error: Variable not in scope: plus
Failed, modules loaded: none.", so I can't try and call the function obviously.
The quotation marks are just part of the syntax of string literals, not their contents. That is, if you write op == "plus", this will be true if (and only if) plus contains the characters 'p', 'l', 'u' and 's' (in that order, obviously) - it does not require (or allow) op to contain any quotes.
So if op == "plus" does not produce True for you even when you think it should, op does not contain what you think it does.

Backslash in string changing output

I am currently trying to implement a method that counts the number of characters and digits in a string. However if I use a string that contains the '\' character I am getting strange results. I am guessing it's because the backslash character is an escape character.
Here is the method:
import Data.Char
countLettersAndDigits :: String -> Int
countLettersAndDigits [] = 0
countLettersAndDigits (x:xs) = if isDigit x == True || isLetter x == True
then 1 + countLettersAndDigits xs
else countLettersAndDigits xs
Here is a set of inputs with their respective results:
"1234fd" -> 6 (Doesn't contain '\')
"1234f\d" -> lexical error in string/character literal at character
'd'
"1234\fd" -> 5
"123\4fd" -> 5
"12\34fd" -> 4
"1\234fd" -> 4
"\1234fd" -> 3
I find it strange that, for example, "1234\fd" and "123\4fd" both give 5 as a result.
Any help explaining why this maybe the case and also how to get around this problem? would be great!
Cheers.
Edit
I forgot to mention that the string that I used above was just an example I was playing with. The actual string that is causing a problem is being generated by Quick Check. The string was "\178". So I require a way to be able to handle this case in my code when their is only one backslash and the string is being generated for me. Cheers.
You are correct that \ is Haskell's escape character. If you print out the generated strings, the answer may be more obvious:
main = mapM_ putStrLn [ "1234fd"
, "1234\fd"
, "123\4fd"
, "12\34fd"
, "1\234fd"
, "\1234fd"
]
yields...
1234fd
1234d
123fd
12"fd
1êfd
Ӓfd
If you actually intended on including a backslash character in your string, you need to double it up: "\\" will result in a single \ being printed.
You can read up on escape sequences here.

Haskell incorrect indentation

I have an error saying "Possibly incorrect indentation"
boyerMooreSearch :: [Char] -> [Char] -> [Int] -> Int
boyerMooreSearch string pattern skipTable
| skip == 0 = 0
| skip > 0 && (string length > pattern length) = boyerMooreSearch (substring string skip (string length)) pattern skipTable
| otherwise = -1
where
subStr = (substring 0 (pattern length))
skip = (calculateSkip subStr pattern skipTable)
Whats wrong with it? Can anyone explain indentation rules in Haskell?
On the line with substr, you have a string of whitespace followed by a literal tab character, and on the line with skip you have the same string followed by four spaces. These are incompatible; one robust, flexible way to get this right is to line things in a block up with exact the same string of whitespace at the beginning of each line.
The real rule, though, since you asked, is that tabs increase the indentation level to the next multiple of eight, and all other characters increase the indentation level by one. Different lines in a block must be at the same indentation level. do, where, let, and of introduce blocks (I may be forgetting a few).

Haskell: lexical error in string/character literal at character 'i'

I'm fairly new to Haskell programming and I'm having trouble understanding why I'm receiving this error in my code.
My problem is as follows: Any positive integer i can be expressed as i = 2^n*k, where k is odd, that is, as a power of 2 times an odd number. We call n the exponent of 2 in i. For example, the exponent of 2 in 40 is 3 (because 40 = 2^3*5) whereas the exponent of 2 in 42 is 1. If i itself is odd, then n is zero. If, on the other hand, i is even, that means it can be divided by 2. Write a function exponentOfTwo for finding the exponent of 2 in its argument.
I understand the psuedocode and it seems fairly simple: recursively divide i by 2 until result is odd, the number of times the division happens is n
here is my code (line 31-32):
exponentOfTwo :: Int -> Int
exponentOfTwo i = if odd i then 0 else 1 + exponentOfTwo (i 'div' 2)
I'm receiving the error "lexical error in string/character literal at character 'i'" on line 32 column 62.
I've tried searching for a solution to this error everywhere and so far I've had no luck.
To use a function in infix for, surround it with backticks (`), not with single quotes ('). The latter are for character literals, which, well are only one character long.
Are the characters around div backquotes rather than normal quotes? They need to be to allow a function name to be used as an infix operator. I changed that in your definition and the code worked for me.

Resources