You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
List.transpose discards data instead of throwing an exception #6908
When List.transpose is given a list containing an empty sublist, all sublists after the empty sublist are discarded.
It's easier to explain by example:
> List.transpose [[true;true];[];[false;false]];;valit:bool list list =[[true];[true]]
compared to:
> Array.transpose [|[|true;true|];[||];[|false;false|]|];;
System.ArgumentException: The arrays have different lengths.
array.[0].Length =2, array.[1].Length =0
Parameter name: array.[0]
at Microsoft.FSharp.Core.DetailedExceptions.invalidArgDifferentArrayLength[?](String arg1, Int32 len1, String arg2, Int32 len2)
at Microsoft.FSharp.Collections.ArrayModule.transposeArrays[T](T[][] array)
at Microsoft.FSharp.Collections.ArrayModule.Transpose[T](IEnumerable`1 arrays)
at <StartupCode$FSI_0018>.$FSI_0018.main@()
Stopped due to error
though the Seq.transpose behavior is understandably quite different.
Provide the steps required to reproduce the problem:
open FSI
enter List.transpose [[true; true]; []; [false; false]];;
Expected behavior
I would expect it to throw an exception just like the Array.transpose implementation, or maybe just filter out empty sublists, such that List.transpose [[true; true]; []; [false; false]] would return [[true; false]; [true; false]]
Actual behavior
List.transpose discards any sublists after the first empty sublist (from what I can tell). For the particular case of List.transpose [[true; true]; []; [false; false]] it returns [[true]; [true]]
Known workarounds
check that all the sublists have the same length before calling transpose, and handling the error case directly.
convert to a seq of arrays and use Array.transpose
Related information
Windows 10
FSI shipped with Visual Studio 2019 16.1.0, particularly
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\FSharp\fsi.exe
I agree that the behavior isn't correct. @PatrickMcDonald any insights or do you concur?
FWIW I could see this going either direction, but given that we don't throw with lists to ease with composition scenarios (see creation of empty ranges or ranges with negative indices) I think it would be more expected to give [[true; false]; [true; false]] as a result.
I'd be happy to accept a PR that changes this behavior if there's no objections.
Also worth noting that it is a breaking change to adjust List to have any changed behavior here, but given that it simply doesn't transpose anything I'd argue that it's worth changing.
I agree this is a bug, and we should probably throw
Note that this situation only occurs when an empty list is passed, the following will throw an exception
> List.transpose [[true;true];[false];[false;false]];;
System.ArgumentException: The lists had different lengths.
list.[1] is 1 element shorter than list.[0]
Parameter name: list.[1]
at Microsoft.FSharp.Core.DetailedExceptions.invalidArgDifferentListLength[?](String arg1, String arg2, Int32 diff)
at Microsoft.FSharp.Primitives.Basics.List.transposeToFreshConsTail[a](FSharpList`1 cons, FSharpList`1 list, Int32 expectedCount)
at Microsoft.FSharp.Primitives.Basics.List.transpose[T](FSharpList`1 list)
at Microsoft.FSharp.Collections.ListModule.Transpose[T](IEnumerable`1 lists)
at <StartupCode$FSI_0008>.$FSI_0008.main@()
Stopped due to error
Activity
cartermp commentedon Jun 3, 2019
I agree that the behavior isn't correct. @PatrickMcDonald any insights or do you concur?
FWIW I could see this going either direction, but given that we don't throw with lists to ease with composition scenarios (see creation of empty ranges or ranges with negative indices) I think it would be more expected to give
[[true; false]; [true; false]]as a result.I'd be happy to accept a PR that changes this behavior if there's no objections.
cartermp commentedon Jun 3, 2019
Also worth noting that it is a breaking change to adjust List to have any changed behavior here, but given that it simply doesn't transpose anything I'd argue that it's worth changing.
PatrickMcDonald commentedon Jun 5, 2019
I agree this is a bug, and we should probably throw
Note that this situation only occurs when an empty list is passed, the following will throw an exception
List.transpose should throw error when given jagged array (dotnet#6908)
List.transpose should throw error when given jagged array (#6908) (#6989