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