'How do I fix "No Instance" error for type in Haskell?

I am working on a function called unzipTriples. It takes a list of triples and it can take any type (polymorphic arguments). The function should return a tuple of three lists where each of the resulting lists consists of the first elements of the triples, the second elements of the triples, and the third elements of the triples. For example, unzipTriples [(1,2,3), (4, 5, 6), (7, 8, 9)] should produce ([1,4,7], [2, 5, 8], [3, 6, 9]).

My first question is, in the base case, should it return a 3-tuple (triple) of 3 empty lists or should it return just an empty 3-tuple?

I am testing it for three empty tuples and I get this error:

For the first test case, I am getting this error:

Couldn't match expected type ‘(Char, Char, Char)’
                  with actual type ‘()’
    • In the expression: ()
      In the first argument of ‘unzipTriples’, namely
        ‘[(1, 2, 3), ('a', 'b', 'c'), ()]’
      In the first argument of ‘shouldBe’, namely
        ‘unzipTriples [(1, 2, 3), ('a', 'b', 'c'), ()]’
   |        
47 |       unzipTriples [(1, 2, 3), ('a', 'b', 'c'), ()] `shouldBe` (([], [], []) :: ([Int], [Char], [Int]))
   |                                                 ^^

For the second one, I am getting this error:

    • No instance for (Data.String.IsString Char)
        arising from the literal ‘"Hello"’
    • In the expression: "Hello"
      In the expression: ("Hello", "World", "!!")
      In the first argument of ‘unzipTriples’, namely
        ‘[(- 1, 2.345, 3.0), ("Hello", "World", "!!"), ('A', 'A', 'A')]’
   |        
59 |       unzipTriples [(-1, 2.345, 3.0), ("Hello", "World", "!!"), ('A', 'A', 'A')] `shouldBe` ([-1, "Hello", 'A'], [2.345, "World", 'A'], [3.0, "!!", 'A'])
   |

The second error is occurring for all types, including 2.345, 'A', and -1. Is there a way I could fix these issues?



Solution 1:[1]

should it return a 3-tuple (triple) of 3 empty lists or should it return just an empty 3-tuple?

An empty 3-tuple makes no sense, () is not an empty 3-tuple. It is the unit type, but even if we assume it is an empty tuple, then it is not a 3-tuple. We need to return a 3-tuple with three lists. If the given list is empty, the only sensical thing to return is a 3-tuple of three empty lists, since we have no value to construct lists with data.

The second error is occurring for all types, including 2.345, 'A', and -1. Is there a way I could fix these issues?

Using () in [(1, 2, 3), ('a', 'b', 'c'), ()] makes no sense. The items of a list all need to have the same type, (1, 2, 3) is a 3-tuple where all items are values of types that are instances of the Num typeclass, whereas () is the unit type.

Furthermore (1, 2, 3) and ('a', 'b', 'c') have different types as well: (1, 2, 3) can have type (Int, Int, Int) (the three items can have different types, but all should be instances of the Num typeclass), whereas ('a', 'b', 'c') has type (Char, Char, Char).

You thus can not construt such a list. You can for example construct a list:

[(1, 'a', "foo"), (4, 'e', "bar")]

here this is a list of 3-tuples where the first item of the 3-tuples is of a type that is an instance of the Num typeclass, the second item has type Char, and the last item has type String. This then for example produces:

ghci> unzipTriples [(1, 'a', "foo"), (4, 'e', "bar")]
([1,4],"ae",["foo","bar"])

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Willem Van Onsem