Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow writing an infix expression with not the same oprand type #1372

Open
6 tasks done
ijklam opened this issue Jun 15, 2024 · 3 comments
Open
6 tasks done

Allow writing an infix expression with not the same oprand type #1372

ijklam opened this issue Jun 15, 2024 · 3 comments

Comments

@ijklam
Copy link

ijklam commented Jun 15, 2024

I propose we allow writing an infix expression with not the same oprand type

(I do not know how to exactly explain it but it is something like this:

let inline (<<) a x =
  (^t: (member Append: _ -> 't) (a, x))
  
let s = System.Text.StringBuilder()
s << 1 << 2 << 'a'

The existing way of approaching this problem in F# is ...

Seperate the line by the oprand types

let inline (<<) a x =
  (^t: (member Append: _ -> 't) (a, x))
  
let s = System.Text.StringBuilder()
s << 1 << 2
s << 'a'

Pros and Cons

The advantages of making this adjustment to F# are make the language consistent

The disadvantages of making this adjustment to F# are no

Extra information

Estimated cost (XS, S, M, L, XL, XXL): Maybe S?

Related suggestions: (put links to related suggestions here)

Affidavit (please submit!)

Please tick these items by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on StackOverflow) and I have searched StackOverflow for discussions of this issue
  • This is a language change and not purely a tooling change (e.g. compiler bug, editor support, warning/error messages, new warning, non-breaking optimisation) belonging to the compiler and tooling repository
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I or my company would be willing to help implement and/or test this

For Readers

If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.

@ijklam
Copy link
Author

ijklam commented Jun 15, 2024

This seems to be allowed with operators defined in types.

type A() =

  static member (+) (a, b: string) = a
  static member (+) (a, b: int)     = a

A() + 1 + "a"

@Martin521
Copy link

Martin521 commented Jun 15, 2024

It seems type checking fixes the type of the Append member of the << operator to int -> StringBuilder once it sees s << 1.
I guess that, theoretically, this could be kept open (allowing for member overloads). But then we might run into the Swift problem that was discussed on the Discord tech channel just two days ago, namely exploding (worst case: exponential) type checking effort.

@T-Gro
Copy link

T-Gro commented Jun 17, 2024

I think this is a bug in the operator typechecking, we did have a few more reported recently when it comes to chaining of operators on the same line.

Note that in this case, neither parens nor duplicate function resolve the bug here, the same issue remains:

let inline (<<) a x =
  (^t: (member Append: 'a -> 't) (a, x))
  
let inline (<<<) a x =
  (^t: (member Append: 'b -> 't) (a, x))  

  
let s = System.Text.StringBuilder()
let res1 = ( s << 1 ) <<< 'c'

FS0001 This expression was expected to have type
'int'
but here has type
'char'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants