Works for me:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 

> type rq<'a> =
-   | Value of 'a
-   | None
-
- type sample_in = { some_value: string rq;}
-
- let do_sample (inp: sample_in) =
-     match inp.some_value with
-     | Value v -> v
-     | None -> ""
- ;;

type rq<'a> =
  | Value of 'a
  | None
type sample_in =
  {some_value: rq<string>;}
val do_sample : sample_in -> string

Can you repro that with a small example?

By on 3/30/2009 7:07 PM ()

this is odd. i started to put together a sample for you, and copied the definition of rq into the same file... and the problem went away. can you try having your type rq<'a> definition in a separate file?

By on 3/30/2009 9:37 PM ()

okay, nevermind. the issue does seem to be related to where the union is defined. when the union is defined in a separate file, i have to explicitly qualify the discriminator value. this works:

1
2
3
4
let do_sample (ctx: IContext) (inp: sample_in) =
    match inp.some_value with 
    | rq.Value v -> v
    | None -> inp.other_value.Val

whereas this doesn't

1
2
3
4
5
6
7
8
9
10
11
12
let do_sample (ctx: IContext) (inp: sample_in) =


    match inp.some_value with 


    | Value v -> v


    | None -> inp.other_value.Val

By on 3/30/2009 9:49 PM ()

okay, nevermind. the issue does seem to be related to where the union is defined. when the union is defined in a separate file, i have to explicitly qualify the discriminator value. this works:

F# automatically puts code that is in a separate file in a separate module, with the same name as the file. You can use the open statement to avoid having to qualify all your usages.

By on 3/31/2009 1:28 AM ()

sure. the open statement was there. still no dice. and take a look at the code - i'm qualifying the type name, not the module.

By on 3/31/2009 6:14 AM ()

sure. the open statement was there. still no dice. and take a look at the code - i'm qualifying the type name, not the module.

I see. Well, it still works for me, even in two files.Maybe you have another discriminated union that has a constructor called Value in the other module? That reproduces a variant (I presume) of the problem. Doesn't make any sense though, since you explicitly give it the type rq. Quite possibly a bug.

By on 3/31/2009 7:38 AM ()

alright, more information. the issue seems to be when i have multiple discriminated unions defined with colliding discriminator names. the original type definition was

1
2
3
4
5
6
    type rq_req<'a> =
        | Value of 'a

    type rq<'a> =
        | Value of 'a
        | None

when i commented out one of them, i no longer had to qualify the type. i'm not sure if it's a bug, but it's certainly confusing. the error message says nothing of a name collision, and conceptually it doesn't make much sense - would the union type be inferred from the type of the match expression?

By on 3/31/2009 7:47 PM ()

The closest I can get to a repro is below, which gives the 'right' diagnostic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 

type rq<'a> =
        | Value of 'a
        | None

type rq_req<'a> =
        | Value of 'a

type sample_in = { some_value: string rq;}

let do_sample (inp: sample_in) =
    match inp.some_value with 
    | Value v -> v  // This expression has type  rq_req<'a> but is here used with type  rq<string>
    | None -> ""

By on 3/31/2009 11:00 PM ()

okay, this is entirely my fault. the classes were named so similarly that i didn't notice it was complaining about rq_req and rq, i thought it was complainging about rq.

thanks guys.

By on 4/1/2009 10:55 AM ()

Kolosy, sorry if this sounds trivial, but do you maybe have another type like:

1
type rq = Value of string | Nothing

which caused you to misread the error message (this kind of overloading, although useful, has bitten me before)?After some more tought I agree with Brian that it's not a bug: even if the compiler knows the type of the expression that is matched against, it should still check whether all cases are consistent with that type.The only thing that is maybe a little bit inconsistent is that if you put both rq types in another file, F# always gives the error in the pattern match. Whereas if you put the types in the same file as the match, the compiler is happy if the correct rq type comes last. (i.e. in the same file, order matters. In different files, order doesn't matter). Note also order of open statements matters: it will given an error on the None match if I open Microsoft.FSharp.Core after I open the rq module. So it could be that you have defined a type rq in another module as well, with a Value constructor, and that this is giving you problems (It doesn't look like types in error messages are fully qualified.)

By on 4/1/2009 12:10 AM ()
IntelliFactory Offices 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