Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Learning Haskell: confusion with reverse function and recursion

Tags:

haskell

I've just started to learn Haskell and I am trying to write a simple function that takes a list of strings and reverses each string in the list:

revComp :: [String] -> [String]
revComp [] = []
revComp [x] = [] ++ [reverse x]
revComp (x:xs) = revComp [xs]

When I try to load my code in GHCI, I get an error:

Couldn't match expected type `Char' with actual type `[Char]'
Expected type: String
Actual type: [String]

Could anyone explain what and where my problem is? Thanks very much.

like image 782
turtle Avatar asked Mar 07 '12 23:03

turtle


2 Answers

The first three lines are fine. Your type signature is correct, the second line is correct, and so is the third. (However, [] ++ [reverse x] is the same as [reverse x].)

The fourth line, however, is wrong. Not only do you not use x at all on the right-hand side, but you have a type error: revComp [xs] calls revComp with a single-element list that has xs as its only element. Here, x is the first element of the list, and xs is the rest of the list. So, since xs has the type [String], [xs] has the type [[String]], but revComp takes a [String]! You want to reverse x, and prepend that to the result of reversing the rest of the list.

You can use revComp xs to reverse each string in the rest of the list, and (:) to prepend a value to a list (with the same syntax seen in the x:xs pattern you used on the left-hand side). That should be enough information for you to fix the last line. This makes the third line redundant, by the way, since [x] is just x:[].

like image 127
ehird Avatar answered Oct 01 '22 22:10

ehird


ehird's answer is really complete, but I wanted to point out -- as a reference -- the "good/shorter" way to implement that function in real code, since you're new. It can be defined as the partial application of map to reverse:

Prelude> let revComp = map reverse
Prelude> revComp ["olleh", "dlrow"]
["hello","world"]

It results in a function revComp :: [[a]] -> [[a]] (and not [String] -> [String] since both map and reverse work on any type of lists) that maps reverse to every element of the input list, returning the list of results.

like image 32
Riccardo T. Avatar answered Oct 01 '22 22:10

Riccardo T.