I'm still learning Haskell and I'm really confused with this language... i have to implement two functions fromInteger :: Integer -> String and toInteger :: String -> Integer that translate between Haskell integers and numbers by strings of digits in reverse order, like: "25" -> "52". For the sake of functional decomposition i should first implement fromDigit :: Integer -> Char and toDigit :: Char -> Integer
that translate between digits and characters.
How should the function look like?
Thanks a lot!
You can use read :: Read a => String -> a and show :: Show a => a -> String to convert from Integer and to a String:
Prelude> show 52
"52"
Prelude> read "52" :: Integer
52
But you do not need to convert values to a string to reverse the order of the digits. You can use recursion and quotRem :: Integral a => a -> a -> (a, a) to obtain the quotient and remainder.
You can also use recursing to convert an Integer to a String. Here we use as accumulator a String, and we each time calculate the last digit. This thus looks like:
fromInteger :: Integer -> String
fromInteger = go []
where go ls x | x <= 9 = … : …
| otherwise = go (… : ls) …
where (q, r) = quotRem x 10
where you still need to fill in the … parts.
Related
I wrote my first program in Haskell today. It compiles and runs successfully. And since it is not a typical "Hello World" program, it in fact does much more than that, so please congrats me :D
Anyway, I've few doubts regarding my code, and the syntax in Haskell.
Problem:
My program reads an integer N from the standard input and then, for each integer i in the range [1,N], it prints whether i is a prime number or not. Currently it doesn't check for input error. :-)
Solution: (also doubts/questions)
To solve the problem, I wrote this function to test primality of an integer:
is_prime :: Integer -> Bool
is_prime n = helper n 2
where
helper :: Integer -> Integer -> Bool
helper n i
| n < 2 * i = True
| mod n i > 0 = helper n (i+1)
| otherwise = False
It works great. But my doubt is that the first line is a result of many hit-and-trials, as what I read in this tutorial didn't work, and gave this error (I suppose this is an error, though it doesn't say so):
prime.hs:9:13:
Type constructor `Integer' used as a class
In the type signature for `is_prime':
is_prime :: Integer a => a -> Bool
According to the tutorial (which is a nicely-written tutorial, by the way), the first line should be: (the tutorial says (Integral a) => a -> String, so I thought (Integer a) => a -> Bool should work as well.)
is_prime :: (Integer a) => a -> Bool
which doesn't work, and gives the above posted error (?).
And why does it not work? What is the difference between this line (which doesn't work) and the line (which works)?
Also, what is the idiomatic way to loop through 1 to N? I'm not completely satisfied with the loop in my code. Please suggest improvements. Here is my code:
--read_int function
read_int :: IO Integer
read_int = do
line <- getLine
readIO line
--is_prime function
is_prime :: Integer -> Bool
is_prime n = helper n 2
where
helper :: Integer -> Integer -> Bool
helper n i
| n < 2 * i = True
| mod n i > 0 = helper n (i+1)
| otherwise = False
main = do
n <- read_int
dump 1 n
where
dump i x = do
putStrLn ( show (i) ++ " is a prime? " ++ show (is_prime i) )
if i >= x
then putStrLn ("")
else do
dump (i+1) x
You are misreading the tutorial. It would say the type signature should be
is_prime :: (Integral a) => a -> Bool
-- NOT Integer a
These are different types:
Integer -> Bool
This is a function that takes a value of type Integer and gives back a value of type Bool.
Integral a => a -> Bool
This is a function that takes a value of type a and gives back a value of type Bool.
What is a? It can be any type of the caller's choice that implements the Integral type class, such as Integer or Int.
(And the difference between Int and Integer? The latter can represent an integer of any magnitude, the former wraps around eventually, similar to ints in C/Java/etc.)
The idiomatic way to loop depends on what your loop does: it will either be a map, a fold, or a filter.
Your loop in main is a map, and because you're doing i/o in your loop, you need to use mapM_.
let dump i = putStrLn ( show (i) ++ " is a prime? " ++ show (is_prime i) )
in mapM_ dump [1..n]
Meanwhile, your loop in is_prime is a fold (specifically all in this case):
is_prime :: Integer -> Bool
is_prime n = all nondivisor [2 .. n `div` 2]
where
nondivisor :: Integer -> Bool
nondivisor i = mod n i > 0
(And on a minor point of style, it's conventional in Haskell to use names like isPrime instead of names like is_prime.)
Part 1: If you look at the tutorial again, you'll notice that it actually gives type signatures in the following forms:
isPrime :: Integer -> Bool
-- or
isPrime :: Integral a => a -> Bool
isPrime :: (Integral a) => a -> Bool -- equivalent
Here, Integer is the name of a concrete type (has an actual representation) and Integral is the name of a class of types. The Integer type is a member of the Integral class.
The constraint Integral a means that whatever type a happens to be, a has to be a member of the Integral class.
Part 2: There are plenty of ways to write such a function. Your recursive definition looks fine (although you might want to use n < i * i instead of n < 2 * i, since it's faster).
If you're learning Haskell, you'll probably want to try writing it using higher-order functions or list comprehensions. Something like:
module Main (main) where
import Control.Monad (forM_)
isPrime :: Integer -> Bool
isPrime n = all (\i -> (n `rem` i) /= 0) $ takeWhile (\i -> i^2 <= n) [2..]
main :: IO ()
main = do n <- readLn
forM_ [1..n] $ \i ->
putStrLn (show (i) ++ " is a prime? " ++ show (isPrime i))
It is Integral a, not Integer a. See http://www.haskell.org/haskellwiki/Converting_numbers.
map and friends is how you loop in Haskell. This is how I would re-write the loop:
main :: IO ()
main = do
n <- read_int
mapM_ tell_prime [1..n]
where tell_prime i = putStrLn (show i ++ " is a prime? " ++ show (is_prime i))
I want to write a program that encrypts a text using XOR-cipher. That's what I have for now:
-- XORres 2 strings
stringXor :: String -> String -> String
stringXor s t = map chr $ zipWith xor (map ord s) (map ord t)
-- encryption and decryption
encDec :: String -> String -> String
encDec text key = stringXor (take (length text) (cycle key)) text
But the output of encDec "this is a test" "k" is
"\US\ETX\STX\CANK\STX\CANK\nK\US\SO\CAN\US"
while I was expecting something like 1f0302184b02184b0a4b1f0e181f4b.
What could be the problem here? I've searched similar questions but that wasn't very helpful.
stringXor s t = map chr $ zipWith xor (map ord s) (map ord t)
You map chr to the results of XOR. This results in characters for each ASCII value. To show the results as hexadecimal, you will need to find a different function to replace chr or write one yourself.
Side note: In cryptography, it is common to use Base64 notation to encode binary data instead of hex because it uses less characters (and therefore less memory or network bandwidth) to represent the same binary sequence.
You are getting 1f0302184b02184b0a4b1f0e181f4b:
> "\x1f\x03\x02\x18\x4b\x02\x18\x4b\x0a\x4b\x1f\x0e\x18\x1f\x4b"
"\US\ETX\STX\CANK\STX\CANK\nK\US\SO\CAN\USK"
...which is exactly the output you saw from encDec (up to what appears to be a simple copy-paste error in your expected output).
The problem is with the chr :: Int -> Char. This function converts an Int to the corresponding character, but not a hexadecimal representation of that number.
You can for example define a utility function with intToDigit :: Int -> Char:
import Data.Char(intToDigit)
toHex2 :: Int -> String
toHex2 h = map intToDigit [d, m]
where (d, m) = divMod h 16
Then we can implement the function as:
stringXor :: String -> String -> String
stringXor s t = concatMap toHex2 (zipWith xor (map ord s) (map ord t))
Or as #DanielWagner says:
import Data.Function(on)
stringXor :: String -> String -> String
stringXor s t = concatMap toHex2 (zipWith (xor `on` ord) s t)
This then gives us:
Prelude Data.Char Data.Bits> encDec "this is a test" "k"
"1f0302184b02184b0a4b1f0e181f"
Note that you do not need to use length here, in fact it is safer without length, you can just use cycle:
encDec :: String -> String -> String
encDec text key = stringXor (cycle key) text
Why it's possible to reduce function in Haskell:
calculate :: Integer -> Integer -> Integer
calculate a b = f 1 a b
where
f :: Integer -> Integer -> Integer -> Integer
f a b c = a + b
into something:
calculate :: Integer -> Integer -> Integer
calculate = f 1
where
f :: Integer -> Integer -> Integer -> Integer
f a b c = a + b
I just need some guidance, any resources where I can find the answer and read more about it would be really helpful.
In Haskell there are no functions that take more than one parameter. All functions take exactly one parameter.
So if you have a function like add :: Int -> Int -> Int, then this is actually short for add :: Int -> (Int -> Int).
Why are the brackets important? Because they show how this concept works. If we have this function add, then we can make a function application with for example 14, then we construct a new function, like:
add14 :: Int -> Int
add14 = add 14
so that means that we now have a function that takes again one parameter (here an Int), and now it will produce another Int, it does that by adding 14 to it, so add14 25 will result in 39.
If you write add 14 25, this thus is not a function application with two parameters, what you actually wrote is:
-- add 14 25 is equivalent to
(add 14) 25
You thus first make a call with 14, and the you make a call with the function that comes out of this, and 25 as the parameter.
Why is this important? Because it means that if you thus write
calculate = f 1
it means that your f 1, constructs a function, a function with signature Int -> (Int -> Int). Creating parameters in the head of calculate, and adding these to the end of f 1, thus makes no sense: you already constructed a function that takes such parameters anyway. So it only introduces noise.
In lambda calculus, the rewrite rule where one rewrites λ x . f x to just f is (and vice versa) is called η-conversion [wiki]. In Haskell it comes down to rewriting:
f x = g x
to:
f = g
Operators are no different. In fact if you write a + b in Haskell, you wrote (+) a b, with (+) a function, or more verbose ((+) a) b.
The f in the where clause:
f a b c = a + b
can for example get converted to:
f = (.) ((.) const) (+)
It's called eta reduction.
You might also think about it in terms of partial application.
> calculate :: Integer -> Integer -> Integer
> f :: Integer -> Integer -> Integer -> Integer
> (f 1) :: Integer -> Integer -> Integer
Similar question - What does eta reduce mean in the context of HLint
I have the following function in Haskell:
invertedSum :: Integer -> Integer
invertedSum n = n + (read . reverse . show) n
I need to know the number of sums that must be made in order for the number to be capicua. That is to say,
invertedSum 1999 = 11990 (1999+9991)
invertedSum 11990 = 21901
invertedSum 21901 = 32813
invertedSum 32813 = 64636
invertedSum 64636 = 128282
invertedSum 128282 = 411103
invertedSum 411103 = 712217
isCapicua :: Integer -> Bool
isCapicua n | show n == (reverse . show) n = True
| otherwise = False
isCapicua 712217 == True
So, I want to generate the following list, but I don't know how.
sumUpToCapicua 1999 = [11990, 21901, 32813, 64636, 128282, 411103, 712217]
genericLength (sumUpToCapicua 1000000079994144385) == 259
You already have a function invertedSum with the type Integer -> Integer. If I understand the question correctly, you'd like to apply it multiple times, starting with a particular Integer (e.g. 1999).
You could use iterate for that purpose. It has the type:
Prelude> :t iterate
iterate :: (a -> a) -> a -> [a]
In other words, it'll take any function a -> a, as well as an initial value a, and produce an infinite list of a values.
In your case, invertedSum has the type Integer -> Integer, and the initial value you'd like to use (e.g. 1999) would also be of the type Integer, so it all fits: a would be Integer.
Try using invertedSum and e.g. 1999 with iterate. Be aware that this produces an infinite list, so if you experiment with this in GHCi, you probably want to use e.g. take 10 to cap the number of values generated.
Modification may well be just an addition of 3 to the Char ascii value.
I have gone through several books and can't find a solution off the shelf.
(Returning the Char list can be to a different list variable.)
import Data.Char
shiftAscii :: String -> String
shiftAscii xs = map (chr.(+3).ord) xs
would do what you ask.
It works because map edits each character in the string using the supplied function.
ord converts the Char to its Int value
(+3) shifts the (ascii) by 3
chr converts back to a Char,
so chr.(+3).ord is those three strung together with function composition .
To be more flexible, you could write
shiftAsciiBy :: Int -> String -> String
shiftAsciiBy n = map (chr.(+ n).ord)
notice that shifting the ascii doesn't respect alphabet boundaries, so if you were needing this to do rot13 encoding or similar simple shift, you'd be better off with a hand-rolled shift function that only edits the alphabet
addAscii :: Int -> Char -> Char
addAscii n c | isUpper c = chr $ ((ord c - ord 'A' + n) `mod` 26) + ord 'A'
| isLower c = chr $ ((ord c - ord 'a' + n) `mod` 26) + ord 'a'
| otherwise = c
for example
['A'..'z']
"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz"
and we shift just the alphabet ascii:
map (addAscii 5) ['A'..'z']
"FGHIJKLMNOPQRSTUVWXYZABCDE[\\]^_`fghijklmnopqrstuvwxyzabcde"