That does look weird. It is probably a type inference subtelty. Can you provide a complete working example, I think that would help us answer your question.Kurt
Ahh, type inference [i]is[/i] the issue. This works:
5.0f * ((Vector3.Normalize Vector3.Forward) : Vector3);;
I don't see why it couldn't determine which overload of Normalize I am using based on the fact that I'm passing in a single argument of type Vector3...
Hi Rotaerk,
If you haven't already, please file a bug report.
thanks,
Danny
Yes, I'll file a bug report once I've confirmed what all is actually buggy behavior.
Pardon the annoying spacing; I haven't figured out this site's BBcode support yet.
Anyway, I found some interesting things related to this issue. Take these C# structs:
namespace TestLibrary
{
public struct TestStruct
{
float value;
public float Value { get { return value; } }
public TestStruct(float value)
{
this.value = value;
}
public static TestStruct operator *(float scalar, TestStruct testStruct)
{
return new TestStruct(scalar * testStruct.Value);
}
public static TestStruct Add(TestStruct a, TestStruct b)
{
System.Console.WriteLine("Add by val");
return new TestStruct(a.Value + b.Value);
}
public static void Add(ref TestStruct a, ref TestStruct b, out TestStruct result)
{
System.Console.WriteLine("Add by ref");
result = new TestStruct(a.Value + b.Value);
}
}
public struct JustByVal
{
float value;
public float Value { get { return value; } }
public JustByVal(float value)
{
this.value = value;
}
public static JustByVal operator *(float scalar, JustByVal testStruct)
{
return new JustByVal(scalar * testStruct.Value);
}
public static JustByVal Add(JustByVal a, JustByVal b)
{
System.Console.WriteLine("Add by val");
return new JustByVal(a.Value + b.Value);
}
}
public struct JustByRef
{
float value;
public float Value { get { return value; } }
public JustByRef(float value)
{
this.value = value;
}
public static JustByRef operator *(float scalar, JustByRef testStruct)
{
return new JustByRef(scalar * testStruct.Value);
}
public static void Add(ref JustByRef a, ref JustByRef b, out JustByRef result)
{
System.Console.WriteLine("Add by ref");
result = new JustByRef(a.Value + b.Value);
}
}
}
I can duplicate the issue I was having with Vector3:
> let a = TestStruct 5.0f
let b = TestStruct 5.0f;;
val a : TestStruct
val b : TestStruct
> 5.0f * (TestStruct.Add(a, b));;
5.0f * (TestStruct.Add(a, b));;
--------^^^^^^^^^^^^^^^^^^^^^
stdin(39,9): error FS0193: Type constraint mismatch. The type
TestStruct
is not compatible with type
float32.
The type 'TestStruct' is not compatible with the type 'float32'.
For some reason, it confuses the two overloads of Add. Removing the by-ref overload results in no error:
> let a = JustByVal 5.0f
let b = JustByVal 5.0f;;
val a : JustByVal
val b : JustByVal
> 5.0f * (JustByVal.Add (a, b));;
Add by val
val it : JustByVal = TestLibrary.JustByVal {Value = 50.0f;}
Removing the by-value overload also results in no error if you tweak the calling code a bit.
> let mutable a = JustByRef 5.0f
let mutable b = JustByRef 5.0f;;
val mutable a : JustByRef
val mutable b : JustByRef
> 5.0f * (JustByRef.Add (&a, &b));;
Add by ref
val it : JustByRef = TestLibrary.JustByRef {Value = 50.0f;}
In F#, you can (optionally) leave off arguments to "out" parameters, and it will return a tuple containing what would be the return value and all values that would have been placed in the omitted "out" parameters. The by-ref overload of TestStruct.Add has the F# type signature: (TestStruct byref * TestStruct byref * TestStruct ref -> unit). However, if you leave off the third argument, it behaves like a function with the signature: (TestStruct byref * TestStruct byref -> TestStruct). There seems to be some kind of clash between overloading and the"out"-parameter omission mechanism, as demonstrated in this code execution:
> let g = (TestStruct.Add : TestStruct byref * TestStruct byref -> TestStruct);;
val g : TestStruct byref * TestStruct byref -> TestStruct
> let h = (TestStruct.Add : TestStruct byref * TestStruct byref * TestStruct ref -> unit);;
val h : TestStruct byref * TestStruct byref * TestStruct ref -> unit
> let x = (JustByRef.Add : JustByRef byref * JustByRef byref -> JustByRef);;
val x : JustByRef byref * JustByRef byref -> JustByRef
> let y = (JustByRef.Add : JustByRef byref * JustByRef byref * JustByRef ref -> unit);;
let y = (JustByRef.Add : JustByRef byref * JustByRef byref * JustByRef ref -> unit);;
---------^^^^^^^^^^^^^^
stdin(50,10): error FS0001: Type mismatch. Expecting a
JustByRef byref * JustByRef byref * JustByRef ref
but given a
JustByRef byref * JustByRef byref.
The tuples have differing lengths of 3 and 2.
As demonstrated by g and x, it actually seems to generate an [i]overload[/i] of Add with the type signature (T byref * T byref -> T). However, it only seems to see the overload with the proper signature of (T byref * T byref * T ref -> unit) in TestStruct. When the by-val overload is removed, the by-ref overload with the proper signature disappears! Although that's not actually the case, because it can still be [i]called[/i] that way:
> let mutable a = JustByRef 5.0f
let mutable b = JustByRef 5.0f
let c = ref (JustByRef 5.0f);;
val mutable a : JustByRef
val mutable b : JustByRef
val c : JustByRef ref
> JustByRef.Add (&a, &b, c);;
Add by ref
val it : unit = ()
A related bug I ran across (which I will definitely report, because it said so) is:
> let g = (TestStruct.Add : TestStruct byref * TestStruct byref * TestStruct ref -> unit);;
val g : TestStruct byref * TestStruct byref * TestStruct ref -> unit
> let h = g;;
error FS0193: internal error: The type 'TestLibrary.TestStruct&' may not be used as a type argument.
Please build a small example that reproduces this problem and report it to fsbugs@microsoft.com.
val h : (TestStruct byref * TestStruct byref * TestStruct ref -> unit)
> let r = (TestStruct.Add : TestStruct byref * TestStruct byref -> TestStruct);;
val r : TestStruct byref * TestStruct byref -> TestStruct
> let s = r;;
error FS0193: internal error: The type 'TestLibrary.TestStruct&' may not be used as a type argument.
Please build a small example that reproduces this problem and report it to fsbugs@microsoft.com.
val s : (TestStruct byref * TestStruct byref -> TestStruct)
> let x = (JustByRef.Add : JustByRef byref * JustByRef byref -> JustByRef);;
val x : JustByRef byref * JustByRef byref -> JustByRef
> let y = x;;
error FS0193: internal error: The type 'TestLibrary.JustByRef&' may not be used as a type argument.
Please build a small example that reproduces this problem and report it to fsbugs@microsoft.com.
val y : (JustByRef byref * JustByRef byref -> JustByRef)
Anyway, I'm considering sending pretty much this whole post in a bug report, but I wanted to get some feedback first.
Looks like you've documented the issue thoroughly. You should report it.Example to quote code (press the quote button, you'll see how the bbcode looks)
1
let codeExample x = match x with None -> true | Some _ -> false
Is there a way to make the code bbcode-tag respect formatting? It did do syntax highlighting but removed all indentation and skipped lines.
I've been unable to duplicate this issue in my own type. Unfortunately, if you want to test this with the Vector3 struct, you will need to download the <a href=http://www.microsoft.com/downloads/details.aspx?FamilyID=7d70d6ed-1edd-4852-9883-9a33c0ad8fee&displaylang=en>MS XNA Game Studio 3.0</a>. If you install that, you can use this to access the Vector3 struct: #r "Microsoft.Xna.Framework.dll" open Microsoft.Xna.Framework <a href=http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector3.aspx>The documentation for Vector3</a>. After a few test cases, it appears that [i]any[/i] static method Vector3.Foo that returns a Vector3 causes that error when applied in this manner: <quote>someFloat32 * (Vector3.Foo args);;</quote> However, [i]these[/i] use cases do not result in the error: <quote>(Vector3.Foo args) * someFloat32;; let foo = Vector3.Foo in someFloat32 * (foo args);;</quote> Looking at the definition of the Vector3 struct (written in C#), it has op_Multiply overloaded as such (bearing in mind that float is a Single in C#): public static Vector3 operator *(float scaleFactor, Vector3 value); public static Vector3 operator *(Vector3 value, float scaleFactor); public static Vector3 operator *(Vector3 value1, Vector3 value2); Given those overloads, I see no reason for the error, but it's as though it doesn't see the first one, and only when expressed in the syntax above.
Topic tags
- f# × 3705
- websharper × 1897
- compiler × 286
- functional × 201
- ui next × 139
- c# × 121
- classes × 97
- web × 97
- .net × 84
- book × 84
- async × 76
- ui.next × 67
- bug × 54
- core × 49
- website × 49
- server × 45
- parallel × 43
- ui × 43
- enhancement × 41
- parsing × 41
- testing × 41
- trywebsharper × 41
- typescript × 37
- html × 35
- javascript × 35
- owin × 35
- asynchronous × 30
- monad × 28
- ocaml × 28
- tutorial × 27
- warp × 27
- haskell × 26
- sitelet × 25
- linq × 22
- workflows × 22
- wpf × 20
- fpish × 19
- introduction × 19
- silverlight × 19
- sitelets × 19
- monodevelop × 17
- rpc × 17
- suave × 17
- piglets × 16
- collections × 15
- feature request × 15
- jquery × 15
- templates × 15
- getting started × 14
- pipeline × 14
- kendoui × 13
- reactive × 12
- 4.1.0.171 × 11
- monads × 11
- opinion × 10
- 4.0.190.100-rc × 9
- deployment × 9
- fixed × 9
- formlets × 9
- in × 9
- json × 9
- plugin × 9
- proposal × 9
- scheme × 9
- solid × 9
- basics × 8
- concurrent × 8
- highcharts × 8
- how-to × 8
- python × 8
- 4.1.1.175 × 7
- complexity × 7
- documentation × 7
- visual studio × 7
- 4.1.2.178 × 6
- lisp × 6
- real-world × 6
- released in 4.0.192.103-rc × 6
- remoting × 6
- resources × 6
- scala × 6
- websharper ui.next × 6
- workshop × 6
- xaml × 6
- 4.0.193.110 × 5
- 4.2.3.236 × 5
- aspnetmvc × 5
- authentication × 5
- azure × 5
- bootstrap × 5
- conference × 5
- dsl × 5
- formlet × 5
- java × 5
- list × 5
- metaprogramming × 5
- ml × 5
- released in Zafir.4.0.188.91-beta10 × 5
- sql × 5
- visualstudio × 5
- websharper.forms × 5
- zafir × 5
- 4.0.192.106 × 4
- 4.0.195.127 × 4
- 4.1.0.38 × 4
- 4.2.1.86 × 4
- 4.2.6.118 × 4
- css × 4
- example × 4
- extensions × 4
- fsi × 4
- fsx × 4
- html5 × 4
- jqueryui × 4
- lift × 4
- reflection × 4
- remote × 4
- rest × 4
- spa × 4
- teaching × 4
- template × 4
- websocket × 4
- wontfix × 4
- 4.0.196.147 × 3
- 4.1.0.34 × 3
- 4.1.6.207 × 3
- 4.2.1.223-beta × 3
- 4.2.11.258 × 3
- 4.2.4.114 × 3
- 4.2.4.247 × 3
- 4.2.5.115 × 3
- 4.2.6.253 × 3
- 4.2.9.256 × 3
- ajax × 3
- alt.net × 3
- aml × 3
- asp.net mvc × 3
- canvas × 3
- cloudsharper × 3
- compilation × 3
- database × 3
- erlang × 3
- events × 3
- extension × 3
- file upload × 3
- forums × 3
- inline × 3
- issue × 3
- kendo × 3
- macro × 3
- mono × 3
- msbuild × 3
- mvc × 3
- pattern × 3
- piglet × 3
- released in Zafir.4.0.187.90-beta10 × 3
- svg × 3
- type provider × 3
- view × 3
- 4.1.1.64 × 2
- 4.1.5.203 × 2
- 4.1.7.232 × 2
- 4.2.10.257 × 2
- 4.2.3.111 × 2
- 4.2.5.249 × 2
- android × 2
- asp.net × 2
- beginner × 2
- blog × 2
- chart × 2
- client × 2
- client server app × 2
- clojure × 2
- computation expressions × 2
- constructor × 2
- corporate × 2
- courses × 2
- cufp × 2
- d3 × 2
- debugging × 2
- direct × 2
- discriminated union × 2
- docs × 2
- elm × 2
- endpoint × 2
- endpoints × 2
- enterprise × 2
- entity framework × 2
- event × 2
- f# interactive × 2
- fable × 2
- flowlet × 2
- formdata × 2
- forms × 2
- fsc × 2
- google maps × 2
- hosting × 2
- http × 2
- https × 2
- iis 8.0 × 2
- install × 2
- interactive × 2
- interface × 2
- iphone × 2
- iteratee × 2
- jobs × 2
- jquery mobile × 2
- keynote × 2
- lens × 2
- lenses × 2
- linux × 2
- listmodel × 2
- mac × 2
- numeric × 2
- oauth × 2
- obfuscation × 2
- offline × 2
- oop × 2
- osx × 2
- packaging × 2
- pattern matching × 2
- performance × 2
- pipelines × 2
- q&a × 2
- quotation × 2
- reference × 2
- released in Zafir.4.0.185.88-beta10 × 2
- rx × 2
- script × 2
- security × 2
- self host × 2
- seq × 2
- sockets × 2
- stm × 2
- tcp × 2
- trie × 2
- tutorials × 2
- type × 2
- url × 2
- var × 2
- websharper.charting × 2
- websharper4 × 2
- websockets × 2
- wig × 2
- xna × 2
- zh × 2
- .net interop × 1
- 2012 × 1
- 4.0.194.126 × 1
- 4.1.3.184 × 1
- 4.1.4.189 × 1
- 4.2.0.214-beta × 1
- 4.2.12.259 × 1
- 4.2.2.231-beta × 1
- 4.2.8.255 × 1
- Canvas Sample Example × 1
- DynamicStyle Animated Style × 1
- Fixed in 4.0.190.100-rc × 1
- Released in Zafir.UI.Next.4.0.169.79-beta10 × 1
- SvgDynamicAttribute × 1
- WebComponent × 1
- abstract class × 1
- accumulator × 1
- active pattern × 1
- actor × 1
- addin × 1
- agents × 1
- aggregation × 1
- agile × 1
- alter session × 1
- animation × 1
- anonymous object × 1
- apache × 1
- api × 1
- appcelerator × 1
- architecture × 1
- array × 1
- arrays × 1
- asp.net 4.5 × 1
- asp.net core × 1
- asp.net integration × 1
- asp.net mvc 4 × 1
- asp.net web api × 1
- aspnet × 1
- ast × 1
- attributes × 1
- authorization × 1
- b-tree × 1
- back button × 1
- badimageformatexception × 1
- bash script × 1
- batching × 1
- binding-vars × 1
- bistro × 1
- body × 1
- bundle × 1
- camtasia studio × 1
- cas protocol × 1
- charts × 1
- clarity × 1
- class × 1
- cli × 1
- clipboard × 1
- clojurescript × 1
- closures × 1
- cloud × 1
- cms × 1
- coding diacritics × 1
- color highlighting × 1
- color zones × 1
- combinator × 1
- combinators × 1
- compile × 1
- compile code on server × 1
- config × 1
- confirm × 1
- content × 1
- context × 1
- context.usersession × 1
- continuation-passing style × 1
- coords × 1
- cordova × 1
- cors × 1
- coursera × 1
- cross-domain × 1
- csla × 1
- current_schema × 1
- custom content × 1
- data × 1
- data grid × 1
- datetime × 1
- debug × 1
- declarative × 1
- delete × 1
- devexpress × 1
- dhtmlx × 1
- dictionary × 1
- directattribute × 1
- disqus × 1
- distance × 1
- do binding × 1
- doc elt ui.next upgrade × 1
- docker × 1
- dojo × 1
- dol × 1
- dom × 1
- domain × 1
- du × 1
- duf-101 × 1
- dynamic × 1
- eastern language × 1
- eclipse × 1
- edsl × 1
- em algorithm × 1
- emacs × 1
- emotion × 1
- enums × 1
- error × 1
- etw × 1
- euclidean × 1
- eventhandlerlist × 1
- examples × 1
- ext js × 1
- extension methods × 1
- extra × 1
- facet pattern × 1
- failed to translate × 1
- fake × 1
- fantomas × 1
- fear × 1
- float × 1
- form × 1
- form-data × 1
- forum × 1
- fp × 1
- frank × 1
- fsdoc × 1
- fsharp × 1
- fsharp.core × 1
- fsharp.powerpack × 1
- fsharpx × 1
- fsunit × 1
- function × 1
- functional style × 1
- game × 1
- games × 1
- gc × 1
- generic × 1
- geometry × 1
- getlastwin32error × 1
- getting-started × 1
- google × 1
- google.maps × 1
- grid × 1
- group × 1
- guide × 1
- hash × 1
- headers × 1
- hello world example × 1
- heroku × 1
- highchart × 1
- history × 1
- how to × 1
- html-templating × 1
- http405 × 1
- httpcontext × 1
- hubfs × 1
- i18n × 1
- ie 8 × 1
- if-doc × 1
- iis × 1
- image × 1
- images × 1
- inheritance × 1
- initialize × 1
- input × 1
- install "visual studio" × 1
- installer × 1
- int64 × 1
- interfaces × 1
- internet explorer × 1
- interop × 1
- interpreter × 1
- io × 1
- iobservable × 1
- ios × 1
- iot × 1
- ipad × 1
- isomorphic × 1
- javascript optimization × 1
- javascript semanticui resources × 1
- jquery-plugin × 1
- jquery-ui × 1
- jquery-ui-datepicker × 1
- js × 1
- kendo datasource × 1
- kendochart × 1
- kendoui compiler × 1
- knockout × 1
- l10n × 1
- learning × 1
- library × 1
- libs × 1
- license × 1
- licensing × 1
- lineserieszonescfg × 1
- local setting × 1
- localization × 1
- logging × 1
- loop × 1
- macros × 1
- mailboxprocessor × 1
- mapping × 1
- maps × 1
- markerclusterer × 1
- markup × 1
- marshal × 1
- math × 1
- mathjax × 1
- message × 1
- message passing × 1
- message-passing × 1
- meta × 1
- metro style × 1
- micro orm × 1
- minimum-requirements × 1
- mix × 1
- mobile installation × 1
- mod_mono × 1
- modal × 1
- module × 1
- mouseevent × 1
- mouseposition × 1
- multidimensional × 1
- multiline × 1
- multithreading × 1
- mysql × 1
- mysqlclient × 1
- nancy × 1
- native × 1
- nested × 1
- nested loops × 1
- node × 1
- nunit × 1
- object relation mapper × 1
- object-oriented × 1
- om × 1
- onboarding × 1
- onclick × 1
- optimization × 1
- option × 1
- orm × 1
- os x × 1
- output-path × 1
- override × 1
- paper × 1
- parameter × 1
- persistence × 1
- persistent data structure × 1
- phonegap × 1
- pola × 1
- post × 1
- powerpack × 1
- prefix tree × 1
- principle of least authority × 1
- privacy × 1
- private × 1
- profile × 1
- programming × 1
- project × 1
- project euler × 1
- projekt_feladat × 1
- protected × 1
- provider × 1
- proxy × 1
- ptvs × 1
- public × 1
- pure f# × 1
- purescript × 1
- qna × 1
- quant × 1
- query sitelet × 1
- question × 1
- quotations × 1
- range × 1
- raphael × 1
- razor × 1
- rc × 1
- reactjs × 1
- real-time × 1
- ref × 1
- region × 1
- released in 4.0.190.100-rc × 1
- reporting × 1
- responsive design × 1
- rest api × 1
- rest sitelet × 1
- restful × 1
- round table × 1
- router × 1
- routing × 1
- rpc reverseproxy × 1
- runtime × 1
- sales × 1
- sample × 1
- sampleapp × 1
- scriptcs × 1
- scripting × 1
- search × 1
- self hosted × 1
- semanticui × 1
- sequence × 1
- serialisation × 1
- service × 1
- session-state × 1
- sharepoint × 1
- signals × 1
- sitelet website × 1
- sitelet.protect × 1
- sitlets × 1
- slickgrid × 1
- source code × 1
- sqlentityconnection × 1
- ssl × 1
- standards × 1
- static content × 1
- stickynotes × 1
- streamreader × 1
- stress × 1
- strong name × 1
- structures × 1
- submitbutton × 1
- subscribe × 1
- svg example html5 websharper.ui.next × 1
- sweetalert × 1
- system.datetime × 1
- system.reflection.targetinvocationexception × 1
- table storage × 1
- targets × 1
- tdd × 1
- templates ui.next × 1
- templating × 1
- text parsing × 1
- three.js × 1
- time travel × 1
- tls × 1
- tooltip × 1
- tracing × 1
- tsunamiide × 1
- turkish × 1
- twitter-bootstrap × 1
- type erasure × 1
- type inference × 1
- type providers × 1
- type-providers × 1
- typeprovider × 1
- ui next forms × 1
- ui-next × 1
- ui.next jqueryui × 1
- ui.next charting × 1
- ui.next formlets × 1
- ui.next forms × 1
- ui.next suave visualstudio × 1
- ui.next templating × 1
- unicode × 1
- unittest client × 1
- upload × 1
- usersession × 1
- validation × 1
- vb × 1
- vb.net × 1
- vector × 1
- view.map × 1
- visal studio × 1
- visual f# × 1
- visual studio 11 × 1
- visual studio 2012 × 1
- visual studio shell × 1
- vs2017 compiler zafir × 1
- vsix × 1
- web api × 1
- web-scraping × 1
- webapi × 1
- webcomponents × 1
- webforms × 1
- webgl × 1
- webrtc × 1
- webshaper × 1
- websharper async × 1
- websharper codemirror × 1
- websharper f# google × 1
- websharper forms × 1
- websharper reactive × 1
- websharper rpc × 1
- websharper sitelets routing × 1
- websharper warp × 1
- websharper-interface-generator × 1
- websharper.chartsjs × 1
- websharper.com × 1
- websharper.exe × 1
- websharper.owin × 1
- websharper.ui.next × 1
- websharper.ui.next jquery × 1
- websockets iis × 1
- why-websharper × 1
- windows 7 × 1
- windows 8 × 1
- windows-phone × 1
- winrt × 1
- www.grabbitmedia.com × 1
- xamarin × 1
- xml × 1
- yeoman × 1
- yield × 1
- zafir beta × 1
- zafir websharper4 × 1
- zarovizsga × 1
![]() |
Copyright (c) 2011-2012 IntelliFactory. All rights reserved. Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy |
Built with WebSharper |
Could someone explain this irregularity?
> 5.0f * (Vector3.Normalize Vector3.Forward);;
5.0f * (Vector3.Normalize Vector3.Forward);;
--------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(5,9): error FS0193: Type constraint mismatch. The type
Vector3
is not compatible with type
float32.
The type 'Vector3' is not compatible with the type 'float32'.
> let f (v:Vector3) = Vector3.Normalize v;;
val f : Vector3 -> Vector3
> 5.0f * (f Vector3.Forward);;
val it : Vector3 = {X:0 Y:0 Z:-5}