Inquirer
Inquirer

Reputation: 101

Splitting a list into a list of lists in Haskell

decodeText is supposed to split' the code into smaller lists Code for each word. Each list of Code is then split into smaller lists of Code for each character in the word.

decodeText :: Table -> Code -> String
decodeText table code=  map (split' shortGap) (split' mediumGap code)

This code gives me this error when I load the program:

Summative2-test.hs:92:25: error:
    • Couldn't match type ‘[[Atom]]’ with ‘Char’
      Expected type: String
        Actual type: [[[Atom]]]
    • In the expression: map (split' shortGap) (split' mediumGap code)
      In an equation for ‘decodeText’:
          decodeText table code
            = map (split' shortGap) (split' mediumGap code)
   |
92 | decodeText table code=  map (split' shortGap)(split' mediumGap code)
   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, one module loaded.

I don't understand where I have made a mistake here.

I am just asking for help with this one small part of the program.

Here is an example:

encodeText morseTable "THIS IS A TEST" = [Beep,Beep,Beep,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Beep,Silence,Beep,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Beep,Silence,Silence,Silence,Silence,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Beep,Silence,Silence,Silence,Silence,Silence,Silence,Silence,Beep,Silence,Beep,Beep,Beep,Silence,Silence,Silence,Silence,Silence,Silence,Silence,Beep,Beep,Beep,Silence,Silence,Silence,Beep,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Beep,Silence,Silence,Silence,Beep,Beep,Beep,Silence]

My intended approach is to split' the Code with the delimeter[Silence,Silence,Silence,Silence,Silence,Silence] at first.

This would give:

[[Beep,Beep,Beep,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Beep,Silence,Beep,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Beep],[Silence,Beep,Silence,Beep,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Beep],
[Silence,Beep,Silence,Beep,Beep,Beep],[Silence,Beep,Beep,Beep,Silence,Silence,Silence,Beep,Silence,Silence,Silence,Beep,Silence,Beep,Silence,Beep,Silence,Silence,Silence,Beep,Beep,Beep,Silence]]

Then, I'm trying to split' each list using [Silence, Silence] as the delimeter.

[[[Beep,Beep,Beep],[Silence,Beep,Silence,Beep,Silence,Beep,Silence,Beep],[Silence,Beep,Silence,Beep],[Silence,Beep,Silence,Beep,Silence,Beep]],[[Silence,Beep,Silence,Beep],[Silence,Beep,Silence,Beep,Silence,Beep]],
[Silence,Beep,Silence,Beep,Beep,Beep],[[Silence,Beep,Beep,Beep],[Silence,Beep],[Silence,Beep,Silence,Beep,Silence,Beep],[Silence,Beep,Beep,Beep,Silence]]]

This code is imported:

module Types where

data Atom = Beep | Silence
  deriving (Eq, Show)

type Code = [Atom]

dit, dah, shortGap, mediumGap :: Code
dit       = [Beep, Silence]
dah       = [Beep, Beep, Beep, Silence]
shortGap  = replicate (3-1) Silence
mediumGap = replicate (7-1) Silence

type Table = [(Char, Code)]

morseTable :: Table
morseTable = [ (c , morseCode c) | c <- ['A'..'Z']++['0'..'9'] ]

Here is my split' function:

   split' :: Eq a => [a] -> [a] -> [[a]]
    split' _ [] = []
    split' [] x = map (:[]) x
    split' a@(d:ds) b@(c:cs)
        | Just suffix <- a `stripPrefix'` b = []:split' a  suffix
        | otherwise = if null rest
                          then [[c]]
                          else (c:head rest):tail rest
      where
          rest = split' a $ tail b

    stripPrefix' :: Eq a => [a] -> [a] -> Maybe [a]
    stripPrefix' [] ys = Just ys
    stripPrefix' (x:xs) (y:ys)
        | x == y = stripPrefix' xs ys
    stripPrefix' _ _ = Nothing

Upvotes: 0

Views: 237

Answers (1)

lsmor
lsmor

Reputation: 5063

The correct type of decodeText would be:

decodeText :: Table -> Code -> [[[Atom]]]
decodeText table code =  map (split' shortGap) (split' mediumGap code)

The type you've written uses String as the returning type. Because String is equal to [Char], the compiler is trying to make [[[Atom]]] equal to [Char], hence the error [[Atom]] doesn't match Char. `

Upvotes: 3

Related Questions