0

I'm sure these are both very stupid mistakes, but i'm trying to convert and print two lists , and i'm getting an error on ghci.

First, i want to convert from this:

["2","2","2"] 

to this

[2,2,2]

for that, i wrote this function:

convert (x:xs) = [read x | x <- xs]

but that doesn't seem to be working...

Second:

Here's my printing function:

print_results [] _ = error("Empty List!")
print_results _ [] = error("Empty List!")
print_results (x:xs) (y:ys) = print x ++ " + " ++ print y : print_results xs ys

For this input:

[2,2,2] and [3,3,3]

The desired output should be:

2 + 3
2 + 3
2 + 3

Thanks in advance!

2 Answers 2

3

These are not "stupid" mistakes, but you're going to have to step back a bit from "what type do I write here" in order to make sense of what's going on. I notice you've asked a bunch of overlapping questions today surrounding these issues. I hope we as a community can get you an answer that will get you on the right track. In that light, I'm marking this post Community Wiki and encouraging others to edit it.

In Haskell, every value has a specific, concrete type. We can write functions that work on multiple types. Some of them work on all types: replicate 5 :: a -> [a] doesn't care at all about what a is. Some work only on some types: read :: Read a => String -> a requires that a be an instance of the class Read.

For now, you should assume that, in order to actually run a function and print a result in GHCi or compiled code, you need to replace all type variables to specific types. (This is wrong in lots of ways that I or others will probably expand on.)

After writing a function, ask GHCi for its inferred type, which is usually the most general signature possible:

> :t map read
map read :: Read a -> [String] -> [a]

> :t map read $ ["as","ew"]
> map read $ ["as","ew"] :: Read a => [a]

Notice that we still have a type variable in there. We need to choose a specific type. What @chi and I both encouraged you to do was to add a type annotation somewhere to fix that type. But if you fix that type to Int, you're trying to parse "as" and "ew" as numbers, which obviously fails.

Sign up to request clarification or add additional context in comments.

2 Comments

So how can i convert it ?
As a first step, why don't you edit your question to add type annotations to all the code blocks. If you have trouble or get it wrong, we can try to help, but I think the exercise will help.
1

First:

convert :: [String] -> [Int]
convert xs = [read x | x <- xs]

or even

convert :: [String] -> [Int]
convert = map read

Note that the type annotation matters, since without it Haskell does not how how it should read the string (as an Int? a Char? a tree? a list? etc.)

Second:

print_results []    []      = []
print_results []     _      = error "Empty List!"
print_results _      []     = error "Empty List!"
print_results (x:xs) (y:ys) = (show x ++ " + " ++ show y) : print_results xs ys

The above will compute a list of strings, formatted as you wanted. If you really want to print them doing an IO action, you can use

mapM_ putStrLn (print_results list1 list2)

6 Comments

When i run the convert function i get this error "[*** Exception: Prelude.read: no parse"
@dcarou That means there's something wrong with your strings.
Because those strings can't be parsed as Ints.
sure @ChristianConkle, but my question is what type do i put in there, so i can convert them
@dcarou If you've told it they you're expecting a list of Ints, you can't try and read a "non-number string". You either have to verify the contents ahead of time (all isDigit xs), or only use it in situations where only Ints are possible. You could set this up as (using the solution in this answer): safeConvertToInts xs | all isDigit xs = convert xs | otherwise = error "Not all elements are numbers!". Add import Data.Char to use isDigit
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.