Is the failure of the 2nd Transpose here a known bug?
Dataset[{{0, 10}, {2, 11}, {3, 12}}][
Transpose /* Map[MinMax] /* Transpose] // Normal
Failure[Transpose, {"MessageTemplate" :> Transpose::nmtx,
"MessageParameters" -> {{__}, Transpose}}]
Similarly for
Dataset[{{0, 10}, {2, 11}, {3, 12}}][
Query[Transpose /* Map[MinMax]] /* Transpose]
For both of these, without the Normal, the error msg is: "The first two levels of {__} cannot be transposed".
Yet the seeming equivalent query, albeit with an intermediate Dataset, works:
Dataset[{{0, 10}, {2, 11}, {3, 12}}][Transpose /* Map[MinMax] ][
Transpose]// Normal
And without Dataset, this works also:
{{0, 10}, {2, 11}, {3, 12}} // Transpose // Map[MinMax] // Transpose
{{0, 10}, {3, 12}}
Answer
The problem is due to two factors:
- The type system cannot infer the data type that results from a call to
MinMax
. - A type-checked application of the
Transpose
query operator will fail when applied to an argument with an unknown type (i.e. fromMinMax
).
I think that point #1 could be considered a bug, although the fact of the matter is that a great many operators are not (yet) known to the type system. Given these omissions, it might be reasonable to expect the Transpose
operator to be more forgiving.
Analysis (current as of version 11.0.1)
When an operation succeeds outside of a Dataset
but fails within, the cause is usually a type-inferencing failure. That is indeed the case here.
traceTypes will reveal the failure:
traceTypes[Dataset[{{0, 10}, {2, 11}, {3, 12}}]][Transpose /* Map[MinMax] /* Transpose]
We can see that the type machinery cannot infer the resultant type of applying MinMax
to a list of integers:
Needs["TypeSystem`"]
TypeApply[MinMax, {Vector[Atom[Integer], 3]}]
(* UnknownType *)
Furthermore, a type-checked application of AssociationTranspose
(the query-form of Transpose
) will not accept a vector of unknown type:
Needs["GeneralUtilities`"]
TypeApply[AssociationTranspose, {Vector[UnknownType, 2]}]
(* FailureType[{Transpose, "nmtx"}, <|"Arguments" -> {__}|>] *)
This last failure is the source of the message we see.
Work-around
As noted in the question, a work-around is to perform the final Transpose
in a second query:
Dataset[{{0, 10}, {2, 11}, {3, 12}}][Transpose /* Map[MinMax]][Transpose]
When the final query result is wrapped back into a dataset, type deduction takes place which is more reliable than type inferencing. By splitting our query in two, we allow such type deduction to take place so that the final Transpose
operator can be applied to a known type:
Needs["Dataset`"]
Dataset[{{0, 10}, {2, 11}, {3, 12}}][Transpose /* Map[MinMax]] // GetType
(* Vector[Vector[Atom[Integer], 2], 2] *)
TypeApply[AssociationTranspose, {Vector[Vector[Atom[Integer], 2], 2]}]
(* Vector[Vector[Atom[Integer], 2], 2] *)
Comments
Post a Comment