Monday, 15 March 2010

type inference - F# assuming int when actually dealing with int64 -



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 int64

since 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