fuzion icon indicating copy to clipboard operation
fuzion copied to clipboard

Tuple with choice type `choice String (array u8)` can not be stored in array

Open simonvonhackewitz opened this issue 1 year ago • 2 comments

Example

ex is
  arr array (tuple (choice String (array u8)) String) :=
    [("foo", "one"),
     ([(u8 65), 66, 67], "two"),
     ("bar", "three")]

  for tup in arr do
    (val, name) := tup
    match val
      str String => say "$name: $str"
      a array u8 => say "$name: {String.type.from_bytes a}"

Error

/tmp/array_choice.fz:5:6: error 1: Incompatible types in array initialization
    [("foo", "one"),

array type          : 'array (tuple (choice String (array u8)) String)'
expected formal type: 'tuple (choice String (array u8)) String'
actual type found   : 'tuple String String'
assignable to       : 'tuple String String'
for value assigned  : '("foo", "one")'
To solve this, you could change the type of the target 'array element' to 'tuple String String' or convert the type of the assigned value to 'tuple (choice String (array u8)) String'.


/tmp/array_choice.fz:6:6: error 2: Incompatible types in array initialization
     ([(u8 65), 66, 67], "two"),

array type          : 'array (tuple (choice String (array u8)) String)'
expected formal type: 'tuple (choice String (array u8)) String'
actual type found   : 'tuple (array u8) String'
assignable to       : 'tuple (array u8) String'
for value assigned  : '([(u8 65), 66, 67], "two")'
To solve this, you could change the type of the target 'array element' to 'tuple (array u8) String' or convert the type of the assigned value to 'tuple (choice String (array u8)) String'.


/tmp/array_choice.fz:7:6: error 3: Incompatible types in array initialization
     ("bar", "three")]

array type          : 'array (tuple (choice String (array u8)) String)'
expected formal type: 'tuple (choice String (array u8)) String'
actual type found   : 'tuple String String'
assignable to       : 'tuple String String'
for value assigned  : '("bar", "three")'
To solve this, you could change the type of the target 'array element' to 'tuple String String' or convert the type of the assigned value to 'tuple (choice String (array u8)) String'.

3 errors.

Without a tuples it works

ex2 is
  arr array (choice String (array u8)) := ["foo", [(u8 65), 66, 67], "bar"]

  for elem in arr do
    match elem
      str String => say str
      a array u8 => say (String.type.from_bytes a)

simonvonhackewitz avatar Jul 12 '24 08:07 simonvonhackewitz

Here, the type propagation should be improved to propagate the tuple type into the array elements. Given the type explicitly

ex is
  arr array (tuple (choice String (array u8)) String) :=
    [(id (String | array u8) "foo", "one"),
     (id (String | array u8) [65, 66, 67], "two"),
     (id (String | array u8) "bar", "three")]

  for tup in arr do
    (val, name) := tup
    match val
      str String => say "$name: $str"
      a array u8 => say "$name: {String.type.from_bytes a}"

works

> ./build/bin/fz ex3370.fz 
one: foo
two: ABC
three: bar

Eventually, with type propagation enhanced and better pattern matching, this should work:

ex is
  arr :=
    [(id (String | array u8) "foo"       , "one"  ),
     (                       [65, 66, 67], "two"  ),
     (                       "bar"       , "three")]

  for tup in arr do
    match tup
      (str String, name) => say "$name: $str"
      (a array   , name) => say "$name: {String.type.from_bytes a}"

fridis avatar Jul 15 '24 08:07 fridis

This also does not work

test_pairs array (tuple i32 u32):= [(1, 2)]

simonvonhackewitz avatar Jul 15 '24 13:07 simonvonhackewitz