hubFS: THE place for F#

. . . are you on The Hub?
Welcome to hubFS: THE place for F# Sign in | Join | Help
in Search

Why is type inference not working here?

Last post 04-09-2009, 9:17 by brianmcn. 4 replies.
Sort Posts: Previous Next
  •  04-08-2009, 4:42 9840

    Why is type inference not working here?

    This might be a newbie question about type inference, but it can help beginners like me.

    I am using the query below - which sorts items by date. This gives the warning: This lookup uses a deprecated feature, where a class type is inferred from the use of a class field label...

    Query.query <@ (Seq.sort_by (fun i -> i.DateAdded) (seq { for item in ctx.BarterItems do yield item }))   |> Seq.take 50 @>;


    In the seq { ... } expression, the type of item is identified as "Item" correctly, through ctx.BarterItems. Why wouldn't this be used to infer "i" in "fun i -> i.DateAdded"? ; Seq.sort_by being (<'a>-><'key>) -> seq<'a> -> seq<'a>

    Explicitly identifying the type will remove the warning, as below:
    Query.query <@ (Seq.sort_by (fun (i:Item) -> i.DateAdded) (seq { for item in ctx.BarterItems do yield item }))   |> Seq.take 50 @>;

  •  04-08-2009, 6:15 9841 in reply to 9840

    Re: Why is type inference not working here?

    Type inference in F# works left-to-right through an expression; for example



    let s = seq { yield "foo"; }

    let s2 = s |> Seq.sort_by (fun x -> x.Length) // compiles

    //let s2 = Seq.sort_by (fun x -> x.Length) s // does not

    In the first one, we already know that the elements of 's' are type 'string' by the time we reach the lambda body and "x.Length".  In the second one, we don't.  This is one of the things that makes the pipelining style so attractive.

  •  04-08-2009, 19:47 9851 in reply to 9841

    Re: Why is type inference not working here?

    Thanks. And good pointer about pipelining style there.
  •  04-09-2009, 8:04 9853 in reply to 9841

    Re: Why is type inference not working here?

    brianmcn:

    Type inference in F# works left-to-right through an expression;



    Is this because the postfix operation is used?

    It seems like inference works (almost) perfectly until I start mixing in a.Idea [I] and obj.doMethod

    Out of curiosity, is there a reason why the compiler can't handle this automatically? It seems to me like all operations could be transformed to left-right in the compiler.
  •  04-09-2009, 9:17 9857 in reply to 9853

    Re: Why is type inference not working here?

    I don't know; I haven't thought about this deeply (I'm sure Don has).  My guess is there are trade-offs, in that if you make the type inference algorithm smarter, you risk

    • having the algorithm take longer (e.g. programs that take forever to compile before finally failing)
    • accidentally making the type-inferencer Turing-complete (don't want to go there)
    • having error messages become less predictable
    • having a more complex mechanism makes it harder for humans to understand/simulate/predict

    Though the type inferencer is pretty powerful today, the three-line summary I gave in a previous message on this thread can often adequately explain its behavior in 95% of situations. 

    (And yes, as it stands, it feels like perhaps > 80% of the 'need to add an annotation' errors come from "o.M" where the type of "o" didn't already flow into this expression from the left; this is one of the few expressions in the language that cannot "float a new constraint" to be solved later, as there is no generic type constraint in .Net that means "forall types 'a where 'a has a method or property named M constrained by this signature".)

View as RSS news feed in XML
Powered by Community Server, by Telligent Systems