user2878641
user2878641

Reputation:

Printing a list in Haskell

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!

Upvotes: 0

Views: 2489

Answers (2)

Christian Conkle
Christian Conkle

Reputation: 5992

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.

Upvotes: 3

chi
chi

Reputation: 116174

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)

Upvotes: 1

Related Questions