0
votes

So I have got this piece of code, which returns an error on it's expected type.

Couldn't match expected type ‘[(Char, b0)]’
with actual type ‘(Char, Int)’
In the expression: newList
In a stmt of a list comprehension: (a, b) <- newList

I want to get the location of the character back, so that would be 'b'. I just don't understand why it gives me a type error. Whenever I run the code one by one inside the WinGHCI, I'll get the correct information back. When putting it in a .hs file, it won't.

word = "apple"
isPart :: Char -> a
isPart x = do
            newList <- zip word [0..length word]
            result <- [b | (a,b) <- newList, a == x]
            return result
1

1 Answers

6
votes

Inside your do block

newList <- zip word [0..length word]

is desugared into something like

zip word [0..length] >>= \newList -> ...

The type of >>= is (Monad m) => m a -> (a -> m b) -> m b.

Since zip returns a list, you are using the list monad and therefore the type of newList is actually an (Int, Char). You cannot then use that as the source for the subsequent list comprehension.

However you don't need to use do at all:

isPart :: Char -> Int
isPart x = let newList = zip word [0..length word]
               result = [b | (a,b) <- newList, a == x]
           in  head result

although be aware this will throw an error if the given character is not in word

You can also write this more simply as

import Data.List (elemIndex)
import Data.Maybe (fromJust)

isPart x = fromJust $ elemIndex x word

although a better solution would be to change the return type to Maybe Int instead of using fromJust.