How can I transform Char to Int in Haskell using "ord" function? - haskell

I have been trying to figure out how can I covert a Char to an Int in Haskell using the "ord" function from the Data.Char library. Here is where I got to now:
charToNum :: Char -> Int
charToNum x = (ord(x))
It is a pretty simple program, but I'm not a 100% sure how to work with an "ord" function
When I run compile the program, everything compiles, but when I try to enter a character I get this error:
> charToNum e
<interactive>:85:11: error: Variable not in scope: e :: Char

e is not a character. I mean, it is of course a character of the string you typed into the prompt, like c and N are characters of that string, but as far as the parser is concerned all of these represent just parts of variable names. And, well, as GHCi then tells you that there is no variable named e.
If you want to pass the character ā€˜eā€™ as an argument then do just that!
> charToNum 'e'

charToNum 'e'?
BTW, your definition should read
charToNum x = ord x
(Or simply
charToNum = ord
)

Related

Error with divides, Haskell

My code, where n = 4:
f n = map (4/) [1..n]
main = do
n <- getLine
print(f (product(map read $ words n :: [Int])))
If I use in terminal map (4/) [1..n] I get a right answer: [4.0,2.0,1.3333333333333333,1.0].
But in my program it's doesn't work, error message is: No instance for (Fractional Int) arising from a use off'`
Where is my mistake?
Your n is an Int which isn't a Fractional type. Those are the ones that support division using the / operator. You can either replace / with div to get integer division (truncates to whole numbers) or you can add fromIntegral to convert the n to the correct type.
Your code should look something like
f n = map (4/) [1..fromIntegral n]
To clarify a bit more: Your function f ultimately does division on the parameter that's given to it. This leads the type inference engine to determine that those parameters should be Fractional types. Then you use that function in your main you explicitly give it an Int.
That's why the error says "You gave me an Int. There's no instance for Fractional Int (read as, 'Int isn't a Fractional type') and I need it to be because you're passing an Int into something that requires that instance."

Haskell: Function that converts Char to Word8

I'm trying to find a function that converts a Char to a Word8, and another that converts it back. I've looked on Hoogle and there are no functions of type Char -> Word8. I want to do this because Word8 has an instance of the Num class, and I would be able to add numbers to them to change them to another number. For example, my function would look something like:
shift :: Char -> Int -> Char
shift c x = toChar $ (toWord8 c) + x
Any ideas?
You can use fromEnum and toEnum to go via Int instead. This has the added benefit of also supporting Unicode.
> toEnum (fromEnum 'a' + 3) :: Char
'd'
I found these using FP Complete's Hoogle: http://haddocks.fpcomplete.com/fp/7.7/20131212-1/utf8-string/Codec-Binary-UTF8-String.html#v:encodeChar
A Char doesn't necessarily contain only one byte, so the conversions you're describing could lose information. Would these functions work instead?

Mapping 3 argument function to a list in Haskell

The map function works fine on really easy functions that take no arguments like *7 to every element in a list of Ints.
But say I made a custom function that takes a Char, String and Int and then returns a Char and I wanted to apply this function to a list of Chars i.e. a String to get a String back after applying the other function to each Char? When I try this all I get is error messages?
Put your Char argument to the last position:
foo :: String -> Int -> Char -> Char
foo str num c = c
bar = map (foo str num)
But we really need some more information from your side to help you better. Can you add the code you tried to write to your question?

Replacing characters with numbers in Haskell

I have started to do the questions on Project Euler regarding lists of names which need to be replaced with their corresponding position in the alphabet. In Problem 22 I need to replace, the letters with numbers:
names = ["MARY","PATRICIA","LINDA"....
replace = ??????
char2num a = map replace a
score (a,b) = a * (sum $ map char2num b)
answer = sum $ map score (zip [1..] (sort names))
What I cannot find is how to replace the characters with their place in the alphabet. How would I go about making something to do the replace function (preferably not regex)?
The ord function in the Data.Char module gives an integer code for each character. Given that, this would be the function you're looking for:
import Data.Char
replace :: Char -> Int
replace c = ord c - ord 'A' + 1
I'm not sure if ord c will return the ASCII code for a character, or the unicode codepoint, or if the result is machine dependent. To abstract from that, we simply subtract the code for 'A' from the result, and add 1 because we want the alphabet to start at 1 instead of 0.
An easy way to find to find such a function is Hoogle.
There you can search for functions in the standard Haskell packages by entering its type. In this case ord is the second result when searching for Char -> Int.

Understanding the type error: "expected signature Int*Int->Int but got Int*Int->Int"

The comments on Steve Yegge's post about server-side Javascript started discussing the merits of type systems in languages and this comment describes:
... examples from H-M style systems where you can get things like:
expected signature Int*Int->Int but got Int*Int->Int
Can you give an example of a function definition (or two?) and a function call that would produce that error? That looks like it might be quite hard to debug in a large-ish program.
Also, might I have seen a similar error in Miranda? (I have not used it in 15 years and so my memory of it is vague)
I'd take Yegge's (and Ola Bini's) opinions on static typing with a grain of salt. If you appreciate what static typing gives you, you'll learn how the type system of the programming language you choose works.
IIRC, ML uses the '*' syntax for tuples. <type> * <type> is a tuple type with two elements. So, (1, 2) would have int * int type.
Both Haskell and ML use -> for functions. In ML, int * int -> int would be the type of a function that takes a tuple of int and int and maps it to an int.
One of the reasons you might see an error that looks vaguely like the one Ola quoted when coming to ML from a different language, is if you try and pass arguments using parentheses and commas, like one would in C or Pascal, to a function that takes two parameters.
The trouble is, functional languages generally model functions of more than one parameter as functions returning functions; all functions only take a single argument. If the function should take two arguments, it instead takes an argument and returns a function of a single argument, which returns the final result, and so on. To make all this legible, function application is done simply by conjunction (i.e. placing the expressions beside one another).
So, a simple function in ML (note: I'm using F# as my ML) might look a bit like:
let f x y = x + y;;
It has type:
val f : int -> int -> int
(A function taking an integer and returning a function which itself takes an integer and returns an integer.)
However, if you naively call it with a tuple:
f(1, 2)
... you'll get an error, because you passed an int*int to something expecting an int.
I expect that this is the "problem" Ola was trying to cast aspersions at. I don't think the problem is as bad as he thinks, though; certainly, it's far worse in C++ templates.
It's possible that this was in reference to a badly-written compiler which failed to insert parentheses to disambiguate error messages. Specifically, the function expected a tuple of int and returned an int, but you passed a tuple of int and a function from int to int. More concretely (in ML):
fun f g = g (1, 2);
f (42, fn x => x * 2)
This will produce a type error similar to the following:
Expected type int * int -> int, got type int * (int -> int)
If the parentheses are omitted, this error can be annoyingly ambiguous.
It's worth noting that this problem is far from being specific to Hindley-Milner. In fact, I can't think of any weird type errors which are specific to H-M. At least, none like the example given. I suspect that Ola was just blowing smoke.
Since many functional language allow you to rebind type names in the same way you can rebind variables, it's actually quite easy to end up with an error like this, especially if you use somewhat generic names for your types (e.g., t) in different modules. Here's a simple example in OCaml:
# let f x = x + 1;;
val f : int -> int = <fun>
# type int = Foo of string;;
type int = Foo of string
# f (Foo "hello");;
This expression has type int but is here used with type int
What I've done here is rebind the type identifier int to a new type that is incompatible with the built-in int type. With a little bit more effort, we can get more-or-less the same error as above:
# let f g x y = g(x,y) + x + y;;
val f : (int * int -> int) -> int -> int -> int = <fun>
# type int = Foo of int;;
type int = Foo of int
# let h (Foo a, Foo b) = (Foo a);;
val h : int * int -> int = <fun>
# f h;;
This expression has type int * int -> int but is here used with type
int * int -> int

Resources