If a function parameter is declared as openarray[char], then I can pass a string to it. But if it's declared as openarray[char | byte], then I can't. Huh?
proc echoKey(key: openarray[char | byte]) =
echo "Key: ", key
var str = "hello"
var bytes: seq[byte] = @[byte(1), 2, 3, 4]
echoKey(bytes) # OK
echoKey(str) # Error: type mismatch
The full error message is:
Error: type mismatch: got <string>
but expected one of:
proc echoKey(key: openArray[char | byte])
first type mismatch at position: 1
required type for key: openArray[char or byte]
but expression 'str' is of type: string
So my next attempt is to explicitly add string to the union type:
type Key = openarray[char | byte] | string
proc echoKey(key: Key) =
echo "Key: ", key
echoKey(str) # OK
echoKey(bytes) # Error: type mismatch: got <seq[byte]>
Now strings work, but byte sequences don't! 🤯
Error: type mismatch: got <seq[byte]>
but expected one of:
proc echoKey(key: Key)
first type mismatch at position: 1
required type for key: Key
but expression 'bytes' is of type: seq[byte]
That was unfortunately reported multiple times but seemto be hard to fix:
I usually use a template as a workaround
template echoKeyImpl(key: openarray[char | byte]) =
echo "Key: ", key
proc echoKey(key: openarray[char]) =
echoKeyImpl(key)
proc echoKey(key: openarray[byte]) =
echoKeyImpl(key)
var str = "hello"
var bytes: seq[byte] = @[byte(1), 2, 3, 4]
echoKey(bytes) # OK
echoKey(str) # Error: type mismatch
see https://github.com/mratsim/Arraymancer/blob/974efe7a/src/tensor/private/p_init_cpu.nim#L32-L42 (a typed template).