The whole problem is in the "magical" properties of the "!=" operator and in the use of the "string" function here.
Look why your code is not working:
The function "string" returns the string value of the first node when the argument is a nodeset. So in your XPath expression you compare the context node's attribute's string-value to the first "foo" element's attribute value.
$A[@type != $B/@type]
is not working again due to the rules for "!=" operator. Actually, "=" operator "returns" true for nodesets NS1 and NS2 as arguments when there is a node n1 in NS1 and node n2 in NS2 such that their string-values are the same. And "!=" is not a logical negation of "=": for 2 nodesets "!=" "returns" true if there is at least one pair of (n1, n2) [n1 is in NS1 and n2 is in NS2] such that their string-values are not the same. Therefore there are situations when "not(NS1 = NS2)" is not equivalent to "NS1 != NS2".
That's why you have to use "not" instead of "!=" here and you have to compare nodesets instead of using"string" function.
The working XPath expression is
$A[not(@type = $B/@type)]