type inference - F# assuming int when actually dealing with int64 -
going through project euler trying larn f#, stumbled upon appears type inference problem while writing solution problem 3.
here's wrote:
class="lang-ml prettyprint-override">let rec findlargestprimefactor p n = if n = 1 p else if n % p = 0 findlargestprimefactor p (n/p) else findlargestprimefactor (p+1) n allow result = findlargestprimefactor 2 600851475143l however, compiler gives me next error:
error fs0001: look expected have type int here has type int64since expect types used in findlargestprimefactor inferred usage, i'm quite surprised find out compiler seems assume parameter n int since in phone call function done int64.
could explain me:
why compiler appears confused types how work around limitation
the types in findlargestprimefactor inferred usage. f# compiler performs type inference in top-to-bottom manner, types of p , n (the parameters of findlargestprimefactor) inferred usage in function. time compiler sees let result = ..., parameter types have been inferred int.
the easiest solution utilize l suffix on of constant values, types inferred int64:
let rec findlargestprimefactor p n = if n = 1l p else if n % p = 0l findlargestprimefactor p (n/p) else findlargestprimefactor (p + 1l) n allow result = findlargestprimefactor 2l 600851475143l if want fancier solution, can utilize generic 1 , 0 constants languageprimitives module. allows findlargestprimefactor generic(-ish) can reused more different numeric types:
open languageprimitives allow rec findlargestprimefactor p n = if n = genericone p else if n % p = genericzero findlargestprimefactor p (n/p) else findlargestprimefactor (p + genericone) n (* can utilize 1 of these, not both @ same time -- types of _arguments_ used infer types of 'p' , 'n'. *) //let result = findlargestprimefactor 2l 600851475143l allow result = findlargestprimefactor 2 int32.maxvalue per @kvb's suggestion, here's how can write function generically:
open languageprimitives allow inline findlargestprimefactor p n = allow rec findlargestprimefactor p n = if n = genericone p else if n % p = genericzero findlargestprimefactor p (n/p) else findlargestprimefactor (p + genericone) n findlargestprimefactor p n (* can phone call function different argument types long generic constraints satisfied. *) allow result = findlargestprimefactor 2l 600851475143l allow result' = findlargestprimefactor 2 int32.maxvalue f# type-inference
No comments:
Post a Comment