-1

Implement a function (myData2Fun) that takes a string as input and expands its compressed representation according to the rules for encoding series lengths. The essence of compression is that consecutive identical characters are combined into one group.For example:

1. Input:  myData2Fun "C"
   Output: [Single "C"] 
2. Input:  myData2Fun "cvvccf"
   Output:[Single 'c',Multiple 'v' 2,Multiple 'c' 2,Single 'f']

It is also necessary to implement the data type required to solve the problem.

I am trying to solve the problem as follows:

data MyData2 = Multiple Char Integer | Single Char deriving(Show)

myData2Fun (h:t) = fff h t 1

fff x (h:t) acc
    | h == x = fff x t (acc + 1)
    | h /= x && acc > 1 = Multiple x acc : fff h t 1
    | h /= x && acc == 1 = Single x : fff h t 1

fff x [] acc
    | acc>0 = Multiple x acc : []
    | acc == 0 = Single x : []

But my program is on a line with a single character, for example Input: myData2Fun "c" returns Output: [Multiple 'c' 1], instead of Output: [Single 'c']. Help me find the error and fix the code.

Yaroslav
  • 87
  • 2
  • 10
  • 1
    here: `| acc > 0 = Multiple x acc : [] | acc == 0 = Single x : []`. – Will Ness Nov 10 '19 at 17:25
  • 1
    At the very end, you map `acc == 0` into `Single x`. That looks wrong. Isn't `acc` the number of occurrences? How can it be 0? It starts from 1 and it is increased, so it is impossible AFAICS. – chi Nov 10 '19 at 17:44
  • Right! It should be like that. Yes? | acc>1 = Multiple x acc : [] | acc == 1 = Single x : [] – Yaroslav Nov 10 '19 at 17:50
  • 1
    yes. In general, to be able to see the code clearer you could try vertically aligning the relevant pieces of code. e.g. like [here](https://repl.it/repls/VividFewKeychanger). (or try [this](https://code.world/haskell#), it has nicer editor) – Will Ness Nov 10 '19 at 18:02
  • 1
    Why the redundant `Single` constructor? – chepner Nov 10 '19 at 20:22
  • 2
    This becomes much simpler if you can use `Data.List.group`. – chepner Nov 10 '19 at 20:33
  • 1
    @chepner to save the replicate call on decoding. – Will Ness Nov 10 '19 at 23:00
  • 1
    Is it really worth saving that call at the expense of complicating the code? Unless you expect a *lot* of isolated values in the string, you won't be saving that many calls anyway. (Besides, you can always just check the integer stored in the `Multiple` value, which replaces the `Single`/`Multiple` check.) – chepner Nov 11 '19 at 13:43

1 Answers1

1

As @chepner hints you may use Data.List.group to simplify your job while keeping your MyData2 data type

import Data.Bool (bool) -- ternary operator
import Data.List (group)

f s = map (\g@(c:_) -> let n = length g
                       in bool (Single c) (Multiple c n) (n > 1)) (group s)

*Main> f "cvvccf"
[Single 'c',Multiple 'v' 2,Multiple 'c' 2,Single 'f']
Redu
  • 25,060
  • 6
  • 56
  • 76