Open frankshearar opened 8 years ago
I ran into this previously too; it's the same as issue #396. The solution is to do this instead:
let rec ``<<``<'a> blahblah =
Hm, it does remove the squigglies... but then I'm defining a function, not an operator. I can't say `1 << myTree``. It's not a massive train smash: it just seems like an unnecessary wart.
That is true--it doesn't really solve the problem the way you (and I) wanted--but agreed; if it can be fixed without breaking existing code, it would be nice, since it certainly seems unintentional and not particularly desirable that it doesn't work as one would expect. (sorry for the noise, just my two cents!)
As a workaround, would something like the following work?
let rec addToFront<'a> (a: 'a) (tree: FingerTree<'a>): FingerTree<'a> =
match tree with
| Empty -> Single a
| Single b -> Deep ([a], Empty, [b])
| Deep ([b; c; d; e], m, suffix) -> Deep ([a; b], addToFront (Node3 (c, d, e)) m, suffix)
| Deep (prefix, m, suffix) -> Deep (List.append [a] prefix, m, suffix)
let (<<) = addToFront
You likely don't need the <'a>
at all - it can be inferred. You could also use let op_LessLess<'a> ...
@PatrickMcDonald That's a clever idea, and does indeed work. Thanks!
@dsyme It can't be inferred because the recursive call is Finger<Node<'a>>, so type inference complains that "The resulting type would be infinite when unifying ''a' and 'Node<'a>'". But using op_LessLess<'a>
does do the trick, with a small wrinkle:
let rec op_LessLess<'a> (a: 'a) (tree: FingerTree<'a>): FingerTree<'a> =
match tree with
| Empty -> Single a
| Single b -> Deep ([a], Empty, [b])
| Deep ([b; c; d; e], m, suffix) -> Deep ([a; b], op_LessLess (Node3 (c, d, e)) m, suffix)
| Deep (prefix, m, suffix) -> Deep (List.append [a] prefix, m, suffix)
The wrinkle is that the recursive call has to use op_LessLess
not <<
, or the compiler thinks I'm calling the default <<
operator. But making the parser special-case the equality of "op_LessLess" with "<<" doesn't seem like a win to me.
In this snippet,
the compiler warns that "Type parameters must be placed directly adjacent to the type name". Presumably that's because the method name is surrounded by ()s.
(I need the
<'a>
because the function takes a FingerTree<'a> but the recursion takes a FingerTree<Node<'a>>.)If I make the operator a function, instead --
-- then everything works.