-3

I need to find an expression for a Haskell function. The function: test :: (c,b,c) -> (b,c,b)

My code of course does not work, because there are "Conflicting definitions for ‘c’".

test (c,b,c) = (b, c, b)
Kabauter
  • 5
  • 3
  • 2
    You can not mention the *same* variable twice in a pattern. What should happen if your tuple contains `(1, 'a', 2)`? Here the "two c's" are simply different. – Willem Van Onsem Jan 07 '19 at 19:57
  • 4
    Don't confuse type variables with patterns. – chepner Jan 07 '19 at 19:58
  • There are two possibilities: `test (a,b,_) = (b,a,b)` and `test (_,b,c) = (b,c,b)`, since the only sensible thing you can do with values of unknown type is copy them from the input to the output. Further constraining the type opens up more possibilities, e.g. `test :: Monoid c => (c,b,c) -> (b,c,b)` allows for `test (a,b,c) = (b,a<>c,b)` and `test (a,b,c) = (b,c<>a,b)` as well. – chepner Jan 07 '19 at 20:00
  • I have to find an expression which general type is the given one of the function test. Edit: test (a,b,_) = (b,a,b) does not work, its not of type (a,b,a) -> (b,a,b). Monoid is not allowed. I have to use the given function. Does it work with a let? – Kabauter Jan 07 '19 at 20:03
  • @Kabauter, `test (a,b,_) = (b,a,b)` has a *more general* type than you specify. But if you actually give it the type signature you specify, it will compile and will have the type you want. – dfeuer Jan 07 '19 at 21:20

1 Answers1

3

As mentioned in the comments, if you want

test :: forall b c. (c, b, c) -> (b, c, b)

(forall added for emphasis)

Then you can't actually do anything with the values in the tuple, since you know nothing about their respective types. So the only two (non-bottom) possible implementations of this function are

test (c, b, _) = (b, c, b)
-- or
test (_, b, c) = (b, c, b)

The first and third elements of the result tuple can only possibly be b, as that's the only value you have of the appropriate type. The second value can be either the first or third original value.

Of course, if you allow bottom, then there are a ton of nonsense functions you can write.

test (a, b, c) = test (c, b, a)
test _ = undefined
test _ = error "Yup, this is definitely a tuple"
test (_, b, c) = (b, c, undefined)

None of these are terribly meaningful, but they will typecheck. For all practical purposes though, only the two non-bottom examples are interesting.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116